Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Web API

mq-web-api is an HTTP/REST server that exposes mq queries over the network. It provides a curl-friendly shortcut endpoint, a JSON API, an OpenAPI specification, and a Swagger UI.

Overview

The server exposes the following endpoints:

MethodPathDescription
GET/healthHealth check
POST/{query}Curl-friendly shortcut: query in the path, raw body (Markdown/HTML/XML/JSON/CSV/…)
GET/api/v1/queryExecute a query (query-string parameters)
POST/api/v1/queryExecute a query (JSON body)
POST/api/v1/batchExecute a query against multiple documents in one request
POST/api/v1/checkType-check a query
POST/api/v1/formatFormat a query
GET/api/v1/functionsList builtin mq functions
GET/api/v1/selectorsList builtin mq selectors
POST/api/v1/lintLint a query
GET/api/v1/openapi.jsonOpenAPI specification
GET/docsSwagger UI

Legacy paths (/api/query, /api/check, /api/format, /openapi.json) redirect permanently to the /api/v1/ equivalents.

A public instance is hosted at https://api.mqlang.org/ for quick trials (rate-limited, see Rate Limiting). For production or higher-volume use, self-host the server yourself (see Usage below).

Configuration

All settings are controlled through environment variables.

Server

VariableDefaultDescription
HOST0.0.0.0Bind address
PORT8080Bind port
RUST_LOGmq_web_api=debug,tower_http=debugLog level filter
LOG_FORMATjsonLog format: json or text
CORS_ORIGINS*Comma-separated allowed origins
QUERY_TIMEOUT_SECONDS10Max seconds a single query may run before it’s aborted

Rate Limiting

VariableDefaultDescription
RATE_LIMIT_REQUESTS_PER_WINDOW100Maximum requests per window
RATE_LIMIT_WINDOW_SIZE_SECONDS3600Window size in seconds
RATE_LIMIT_CLEANUP_INTERVAL_SECONDS3600Expired-entry cleanup interval

OpenTelemetry (requires otel feature)

VariableDefaultDescription
OTEL_EXPORTER_OTLP_ENDPOINTOTLP exporter endpoint (e.g. http://localhost:4317)
OTEL_SERVICE_NAMEmq-web-apiService name reported to the collector

Usage

Running locally

# Default settings
cargo run --bin mq-web-api

# Custom host and port
HOST=localhost PORT=3000 cargo run --bin mq-web-api

# Text-format logs
LOG_FORMAT=text cargo run --bin mq-web-api

# Restrict CORS origins
CORS_ORIGINS="https://example.com,https://app.example.com" cargo run --bin mq-web-api

# Enable OpenTelemetry
cargo run --features otel --bin mq-web-api

Docker

Build and run from the workspace root:

docker build -f crates/mq-web-api/Dockerfile.vercel -t mq-web-api .
docker run -p 8080:8080 mq-web-api

With custom configuration:

docker run -p 3000:3000 \
  -e PORT=3000 \
  -e LOG_FORMAT=text \
  -e CORS_ORIGINS="https://example.com" \
  mq-web-api

Examples

Curl-friendly shortcut

The mq query goes in the URL path; the input content is the raw request body.

curl --data-binary @doc.md https://api.mqlang.org/.h1

html, xml, and json input are auto-detected from the body’s leading bytes. Other formats (csv, tsv, psv, yaml, toml, hcl, toon) need an explicit input_format:

curl --data-binary @page.html https://api.mqlang.org/.h1
curl --data-binary @data.json 'https://api.mqlang.org/json::json_to_markdown_table()'
curl --data-binary @data.csv 'https://api.mqlang.org/csv::csv_to_markdown_table()?input_format=csv'

Use --data-binary, not -d/--data. curl -d @file strips newlines from the file, which breaks Markdown/HTML/XML parsing. --data-binary sends the file exactly as-is.

For queries that need modules, args, or aggregate, use POST /api/v1/query instead.

Execute a query (GET)

curl "http://localhost:8080/api/v1/query?query=.h&input=%23%20Title%0A%0AContent&input_format=markdown"

Execute a query (POST)

curl -X POST http://localhost:8080/api/v1/query \
  -H "Content-Type: application/json" \
  -d '{
    "query": ".h",
    "input": "# Title\n\nContent",
    "input_format": "markdown"
  }'

Batch query (multiple documents in one request)

POST /api/v1/batch runs one query against multiple documents in a single request, avoiding an HTTP round trip per document. Each document is processed independently — one failing document doesn’t fail the others, and items in the response is ordered like inputs (max 100 entries).

curl -X POST http://localhost:8080/api/v1/batch \
  -H "Content-Type: application/json" \
  -d '{
    "query": ".h1",
    "inputs": ["# Doc One\n\nBody.", "# Doc Two\n\nBody."],
    "input_format": "markdown"
  }'

Type-check a query

curl -X POST http://localhost:8080/api/v1/check \
  -H "Content-Type: application/json" \
  -d '{"query": "upcase | downcase"}'

Format a query

curl -X POST http://localhost:8080/api/v1/format \
  -H "Content-Type: application/json" \
  -d '{"query": "if(a):1 elif(b):2 else:3"}'

Lint a query

curl -X POST http://localhost:8080/api/v1/lint \
  -H "Content-Type: application/json" \
  -d '{"query": "let x = .h1 | .text"}'

List builtin functions and selectors

curl http://localhost:8080/api/v1/functions
curl http://localhost:8080/api/v1/selectors

Features

FeatureDefaultDescription
use_mimallocenabledUse mimalloc as the global allocator
oteldisabledEnable OpenTelemetry tracing via OTLP

See the mq-web-api crate for the full README and source.