REST API · keyset pagination · JSON in, JSON out
Read-only REST access to the full dataset. Bearer-token auth, keyset pagination, RFC 9457 errors, and ETag caching. Paid plans include API access; agents and one-off callers can pay per row without a subscription.
API response fixture — no purchase
The keyless endpoint and free key use a small response fixture for integration testing. They are not the 150-record evaluation sample delivered by email and should not be searched as if they represented full coverage.
Keyless — call the API fixture endpoints with no token at all. Add ?sample=1 explicitly; a bare full-data request starts the payment flow:
# list records
curl "https://api.rxatlas.dev/v1/drugs?sample=1&limit=5"
# fetch one record — use any id from the list above
curl "https://api.rxatlas.dev/v1/drugs/{id}?sample=1"Free key — sign in at the portal for a rxatlas_live_… token scoped to the API preview fixture with a higher daily limit (100/day vs. 60/day per IP keyless).
Base URL and versioning
https://api.rxatlas.dev/v1URL prefix is versioned. v1 is supported for the lifetime 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) remain on the same version.
Authentication
One bearer token per customer, scoped to the organisation. Pass it in the Authorization header:
curl "https://api.rxatlas.dev/v1/drugs/{id}" \
-H "Authorization: Bearer rxatlas_live_····"?sample=1 to opt into the keyless API fixture instead (see Try it free).Agent payments (x402 or MPP)
A client can buy one full-data call without a subscription or sales call. Send a bare request to receive a 402 quote, settle it over x402 (USDC on Base) or MPP (USDC on Base and Tempo), then retry with the payment proof. A settled call returns the full paid record; it does not mint an API token.
GET /v1/drugs/{id} $0.025 per row
GET /v1/drugs?… $0.10 per search page
GET /v1/coverage $0.25 per coverage callcurl -i "https://api.rxatlas.dev/v1/drugs/{id}"
# → 402 Payment Required
# x402 v2: decode PAYMENT-REQUIRED, then retry with PAYMENT-SIGNATURE.
# A successful v2 settlement returns PAYMENT-RESPONSE.
# x402 v1 compatibility: read the JSON body, retry with X-PAYMENT,
# and read X-PAYMENT-RESPONSE after settlement.
# MPP: read offers from WWW-Authenticate, then retry with
# Authorization: Payment <credential>; the response includes Payment-Receipt.
# To use the free API response fixture instead, append ?sample=1.Endpoints
GET /v1/drugs
Filtered list, 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).
GET /v1/drugs?limit=2
→ 200 OK
{
"data": [ { "id": 1, ... }, { "id": 2, ... } ],
"has_more": true,
"next_cursor": "eyJhIjoxNjc4fQ"
}GET /v1/drugs/{id}
Full record by ID, including the _provenance subtree for every populated field. No separate call required — every record response carries inline provenance.
Pack examples
These examples reflect the workflows buyers naturally test first, from search and record retrieval to source inspection.
Resolve a product NDC
Resolve an FDA product NDC through authenticated production access.
curl "https://api.rxatlas.dev/v1/drugs?ndc=75834-258&limit=5" \
-H "Authorization: Bearer rxatlas_live_····"Fetch one canonical product
Inspect one canonical drug product with provenance and cross-source IDs.
curl "https://api.rxatlas.dev/v1/drugs/147244" \
-H "Authorization: Bearer rxatlas_live_····"List data sources
Inspect the source registry behind the delivered dataset.
curl "https://api.rxatlas.dev/v1/sources" \
-H "Authorization: Bearer rxatlas_live_····"Rate limits
Paid tier: 60 requests/second per token, 50,000 requests/day — enterprise agreements lift these. Free preview key: 2/second, 100/day. Keyless API fixture: 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. On a breach the response is 429 with Retry-After.
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://rxatlas.dev/docs/api#errors/not_found",
"title": "Not found",
"status": 404,
"detail": "Record 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 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.rxatlas.dev/v1/openapi.json — generate a typed client, import into Postman, or render interactive docs.
Data freshness
The API serves the live rolling database. Corrections and new coverage are published as they arrive. Snapshot-tier customers receive versioned Parquet/CSV/SQLite bundles when releases ship; the API tier reflects the DB as it stands at query time.
Related evaluation guides
Connect this diligence evidence to the relevant integration decision.