REST API · same data, query at launch · JSON in, JSON out
The Snapshot + API SKU includes 12 months of read-only REST access to the same data shipped in the snapshot. Read endpoints only. Subscribers pay no per-call fees; an agent without a subscription can pay per call instead — see Agent payments.
At launch the API will be a live query surface: portfolio lookups, model-line drill-downs, BI dashboards. Whole-dataset analytical work is faster and cheaper against the JSON, CSV, SQLite, or Parquet snapshot.
API response fixture — no purchase
Keyless calls and free keys use a small response fixture for integration testing. It is not the canonical 133-variant evaluation sample; request that downloadable bundle by email at /sample.
Keyless — add ?sample=1 to opt into the API response fixture with no token. A bare call without it returns 402 by default (the pay-per-call prompt). Fastest way to see the shape and the citations:
# list API fixture variants — sample=1 opts into the technical preview
curl "https://api.apex-db.org/v1/apex?sample=1&limit=5"
# get one variant in full — use an id from the list call above
curl "https://api.apex-db.org/v1/apex/{id}?sample=1"Free key — sign in at the portal with your email for a free_sample token: same API fixture, a higher daily limit (100/day vs 60/day per IP keyless).
/coverage and bulk portfolio lookups, need the Snapshot + API tier.Base URL and versioning
https://api.apex-db.org/v1URL prefix is versioned. v1 is supported for the life of every snapshot it shipped under, plus the following one. Breaking changes ship under a new prefix; non-breaking additions (new optional fields, new endpoints) stay on the same version.
Authentication
One bearer token per customer, scoped to the org. Pass it in the Authorization header.
curl https://api.apex-db.org/v1/apex/95124 \
-H "Authorization: Bearer apex_live_····"?sample=1 to get the keyless API fixture instead (see API response fixture).Agent payments (x402 or MPP)
An autonomous agent can buy a single call without a subscription or a sales call. A bare request returns an x402 HTTP-402 quote settled in USDC on Base.
A bare request 402s by default. The free API fixture is an opt-out: add ?sample=1 to the URL, or send X-Payment-Intent: sample. X-Payment-Intent: full is still accepted but not required — a bare request already triggers the payment flow. Send the bare request to get a quote, then retry with the proof header. A settled call returns the full (non-sample) row, priced per call:
GET /v1/apex/{id} $0.025 per row
GET /v1/apex?… $0.10 per search page
GET /v1/coverage $0.25 per coverage callThe discovery handshake — send a bare request, read the quote from the 402:
curl -i "https://api.apex-db.org/v1/coverage"
→ 402 Payment Required
# x402 v2: decode PAYMENT-REQUIRED, then retry with PAYMENT-SIGNATURE;
# read PAYMENT-RESPONSE after settlement.
# x402 v1 compatibility: read the JSON body, retry with X-PAYMENT,
# and read X-PAYMENT-RESPONSE after settlement.
# MPP: read WWW-Authenticate, then retry with
# Authorization: Payment <credential>; read Payment-Receipt.
# To opt out to the free API fixture instead: append ?sample=1 or send
# X-Payment-Intent: sample.Endpoints
GET /v1/apex
Filtered list of variants, keyset-paginated. The envelope is data, has_more, and an opaque next_cursor — pass it back as ?cursor= for the next page. An exact total is returned only with ?count=true (best-effort, slower). The model parameter matches the model line (e.g. 5 Series, i4), not the variant trim name.
GET /v1/apex?brand=bmw&model=5%20Series&model_year=2024&limit=2&count=true
→ 200 OK
{
"data": [ { "id": ..., "brand": "BMW", "model": "5 Series", ... } ],
"total": 5,
"has_more": true,
"next_cursor": "eyJhIjoxNjc4fQ"
}GET /v1/apex/{id}
Full variant row by ID, including the _provenance subtree for every populated field.
Provenance is inline — no separate call. Every /v1/apex and /v1/apex/{id} response carries a _provenance subtree with per-field source attribution. The complete candidate set — including superseded and non-winning values — ships in the downloadable snapshot’s provenance table. See Provenance → Conflict resolution.
GET /v1/coverage
The live coverage matrix powering the /docs/coverage page. Suitable for customer-side freshness dashboards.
Rate limits
Paid tier: 60 requests/second per token, 50,000 requests/day — enterprise agreements lift these. Free key: 2/second, 100/day. Keyless sample: 2/second, 60/day per IP. Headers on every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1716624000
RateLimit-Policy: "rps";q=60;w=1, "daily";q=50000;w=86400
RateLimit: "rps";r=57;t=1, "daily";r=49873;t=64802Both the legacy X-RateLimit-* headers and the IETF RateLimit / RateLimit-Policy structured fields are emitted (rps and daily policies named separately). On a breach the response is 429 with Retry-After. Higher throughput is served by the snapshot file — the API is scoped to live lookups, not bulk extraction.
Error semantics
Errors follow RFC 9457 (application/problem+json) with a stable machine-readable code and a request_id on every response. HTML is never returned.
404 → {
"type": "https://apex-db.org/docs/api#errors/not_found",
"title": "Not found",
"status": 404,
"detail": "apex 99999 does not exist.",
"code": "not_found",
"request_id": "req_····"
}
// codes: unauthenticated 401 · scope_exceeded 403 · not_found 404
// rate_limited 429 (+retry_after_ms) · validation 400 · internal 500Caching & request IDs
Single-resource reads (/v1/apex/{id} and /v1/coverage) carry a strong ETag and Cache-Control; send If-None-Match to get a 304 Not Modified and save bandwidth. Every response carries X-Request-Id — quote it in support tickets.
OpenAPI
A machine-readable OpenAPI 3.1 description is served (unauthenticated) at https://api.apex-db.org/v1/openapi.json — generate a typed client, import into Postman, or render interactive docs.
Data freshness
At launch the API will serve the live rolling database — corrections and new coverage flow continuously on an ad-hoc basis, with no fixed quarterly or annual schedule. Snapshot SKU customers receive versioned JSON, CSV, SQLite, and Parquet bundles when releases ship; the API tier reflects the DB as it stands at query time.