latest update:
[RxAtlas]

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:

curl (no auth)bash
# 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).

Free API tiers serve only the small response fixture. Request the 150-record bundle at /sample for evaluation, use a paid plan for ongoing access, or pay $0.025 for one full row without a subscription.

Base URL and versioning

http
https://api.rxatlas.dev/v1

URL 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:

curlbash
curl "https://api.rxatlas.dev/v1/drugs/{id}" \
  -H "Authorization: Bearer rxatlas_live_····"
Tokens are generated in the customer portal and self-rotatable. Previous tokens remain valid for 24 h to allow deployment rollover. A request with no Authorization header starts the 402 payment flow by default. Add ?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.

http
GET /v1/drugs/{id}  $0.025 per row
GET /v1/drugs?…     $0.10 per search page
GET /v1/coverage            $0.25 per coverage call
curl (quote)bash
curl -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.
Each settled call is a separate, immediate machine transaction. It creates no account, confirmation email, or order reference; keep the protocol receipt and on-chain transaction reference as your purchase record. See the Terms and pay-per-call refund process. For sustained traffic, compare the snapshot and API licences on the pricing page.

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).

http
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.

curlbash
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.

curlbash
curl "https://api.rxatlas.dev/v1/drugs/147244" \
  -H "Authorization: Bearer rxatlas_live_····"

List data sources

Inspect the source registry behind the delivered dataset.

curlbash
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:

http
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=64802

Both 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.

json
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 500

Caching & 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.