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 152-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.trialbase.dev/v1/trials?sample=1&limit=5"
# fetch one record — use any id from the list above
curl "https://api.trialbase.dev/v1/trials/{id}?sample=1"Free key — sign in at the portal for a trialbase_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.trialbase.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.trialbase.dev/v1/trials/{id}" \
-H "Authorization: Bearer trialbase_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/trials/{id} $0.025 per row
GET /v1/trials?… $0.10 per search page
GET /v1/coverage $0.25 per coverage callcurl -i "https://api.trialbase.dev/v1/trials/{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/trials
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/trials?limit=2
→ 200 OK
{
"data": [ { "id": 1, ... }, { "id": 2, ... } ],
"has_more": true,
"next_cursor": "eyJhIjoxNjc4fQ"
}GET /v1/trials/{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.
Search by registry identifier
Search authenticated production access for a registry identifier and source link.
curl "https://api.trialbase.dev/v1/trials?q=ISRCTN17465883&limit=5" \
-H "Authorization: Bearer trialbase_live_····"Fetch one canonical trial
Inspect one included trial record with registry provenance.
curl "https://api.trialbase.dev/v1/trials/679751" \
-H "Authorization: Bearer trialbase_live_····"List data sources
Inspect commercial source terms and registries represented in the delivered dataset.
curl "https://api.trialbase.dev/v1/sources" \
-H "Authorization: Bearer trialbase_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://trialbase.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.trialbase.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.