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 (source) 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
MAX_REQUEST_BODY_SIZE10485760Max accepted HTTP request body size, in bytes. Larger requests get 413 Payload Too Large
REQUEST_TIMEOUT_SECONDS30Max seconds a single HTTP request may take end-to-end (routing, auth, rate limiting, handler). Exceeding it returns 408 Request Timeout

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

Authentication

Disabled by default. When AUTH_ENABLED=true, every endpoint except /health, /docs, and the OpenAPI spec requires Authorization: Bearer <key>. Keys carry a scope (read: functions/selectors/check/format/lint, query: /api/v1/query, /api/v1/batch, /{query}) and an optional rate limit override enforced independently of the IP-based limit above.

VariableDefaultDescription
AUTH_ENABLEDfalseRequire an API key on protected endpoints
API_KEYS-Comma-separated keys; each gets both scopes and no rate limit override
API_KEYS_FILE-Path to a JSON file for per-key name/scopes/rate limit (takes precedence over API_KEYS)

API_KEYS_FILE format:

[
  { "key": "sk_live_...", "name": "acme-corp", "scopes": ["read", "query"], "rate_limit_per_window": 5000 },
  { "key": "sk_live_...", "name": "acme-readonly", "scopes": ["read"] }
]

scopes defaults to ["read", "query"] when omitted; rate_limit_per_window defaults to the server-wide RATE_LIMIT_REQUESTS_PER_WINDOW.

OpenTelemetry (requires otel feature)

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

Usage

Running locally

Clone harehare/mq-web-api, then:

# 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 repository root:

docker build -f 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"}'

Authenticated request (when AUTH_ENABLED=true)

curl -H "Authorization: Bearer sk_live_..." \
  -X POST http://localhost:8080/api/v1/query \
  -H "Content-Type: application/json" \
  -d '{"query": ".h1", "input": "# Title"}'

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 repository for the full README and source.