Agents welcome.

keyless · signed · discoverable

DomainDrift is built to be read by machines. It continuously observes ~809,000 domains plus any domain you add, and serves every observation as Ed25519-signed JSON you can verify offline. No HTML to parse, and no key for a first look. If you are an agent, start here.

Quick start

# keyless: one domain, latest, a reduced signed-record preview
curl https://domaindrift.io/v1/domains/example.com

# keyed: the COMPLETE record + higher volume (a DRM3 account mints the key)
curl -H "X-DomainDrift-Key: dd_..." https://domaindrift.io/v1/domains/example.com
# Authorization: Bearer dd_... works too. Legacy keys and headers are still accepted.
  • Every record is a signed observation. The receipt for a snapshot: GET /v1/domains/:domain/provenance. Any receipt by id: GET /receipts/:id. The signing keys: GET /.well-known/domaindrift-keys.json.
  • A signature proves attribution and integrity. It is added trust, not a claim of correctness.
  • Keyless is a preview. 1 request per 15 seconds per IP under a shared daily ceiling. Derived facts (providers, cert issuer and expiry, reachability, scan time) and per-type record COUNTS, plus the receipt pointer. No signature: a signature commits to the FULL record's bytes and cannot verify a reduced subset.
  • Keyed is the complete record on your metered allowance.

Discovery

Point your agent at any of these. They are static, keyless, and machine-readable.

GET/v1/openapi.json
OpenAPI 3.1 - every endpoint and schema.
GET/.well-known/domaindrift-keys.json
The Ed25519 public keys that sign every observation. Verify offline.
GET/receipts/:id
Resolve any provenance receipt by id (public commitment).
GET/llms.txt
A plain-text map of the site and API for language models.
GET/llms-full.txt
The long-form version: the full machine-readable brief.
GET/badge/:domain.svg
An embeddable signed status badge for any domain.
GET/v1/tape
The 24-hour rollup as JSON. CORS-open, safe to embed.
POST/mcp
The MCP server: five read-only tools over the same lanes as the API.
GET/.well-known/mcp.json
The MCP descriptor: endpoint, transport, auth posture.

Connect over MCP

  • Read-only MCP server at https://domaindrift.io/mcp (streamable HTTP, stateless). Five tools: one domain, today's change digest, a receipt, the 24-hour tape, the signing keys.
  • Every tool is a name for an existing HTTP route, on the same lanes as this page: keyless tool calls get the preview under the same per-IP throttle and shared daily ceiling; Authorization: Bearer on the connection opens the complete record on your allowance. MCP uses the same pay gate as the API.
# Claude Code
claude mcp add --transport http domaindrift https://domaindrift.io/mcp
# Claude on the web: Settings > Connectors > Add custom connector, URL https://domaindrift.io/mcp
# ChatGPT developer mode, and any streamable-HTTP MCP client: the same URL

DomainDrift also measures who else speaks MCP, by fetching a domain's /.well-known/mcp.json and checking that what comes back is a descriptor rather than merely a response. See who speaks MCP for the running index, and the connect guide for Claude, Claude Code, and ChatGPT developer mode.

See who has already employed MCP Of 180,588 domains asked for an MCP descriptor, 26 serve one.

The data endpoints

Reads. The single-domain lookup has a keyless preview (above); everything else needs a key.

GET/v1/domains
List + filters (category, tag, search); ?format=csv for a download.
GET/v1/domains/:domain
The latest signed record (keyless: reduced preview; keyed: full).
GET/v1/domains/:domain/history
The snapshot time series for one domain.
GET/v1/domains/:domain/provenance
The Ed25519 receipt chain for one domain.
GET/v1/domains/:domain/planes
Latest observation per plane + completeness.
GET/v1/changes
The global change feed (structured deltas), with sync cursors.
GET/v1/stream
Live Server-Sent Events: scans, changes, receipts.
GET/v1/stream/json
The polling fallback for clients that cannot hold an SSE.
GET/v1/groups
Your bring-your-own-domain monitoring groups.
GET/v1/evidence/:domain
A printable, signed evidence report for auditors.
GET/v1/domains/:domain/bundle
A signed, offline-verifiable export bundle (paid, rate-capped).

Try it right now, with no key

One domain, no account, a real slice of the signed record. Keyless calls are throttled to 1 request every 15 seconds per IP - useful for "does this work?", useless for real work. An API key removes the throttle.

The response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Go too fast and you get a 429 with Retry-After - a boundary, not a bug. Lists, history, and exports need a key.

Keyless, right now
curl https://domaindrift.io/v1/domains/netflix.com
200 with a reduced preview plus the receipt that commits to the full signed record - the preview itself is deliberately unsigned, and says so. A second call within 15s answers 429 with Retry-After - the boundary is in the headers, never a surprise.

What is public, what is metered

DomainDrift states its price at the door. Every metered response carries its own meter in the headers, so you never have to guess where you stand.

Public / webNot metered
$0
Anyone. No key, no account.

The public web surface, no account. Rate-limited per IP so the wire stays up.

How the meter works

Not metered. Rate limited per IP only, to keep the wire up.

/health/t/:domain (the time machine)/changes/today, /changes/:date/changes.rss, /changes.json/v1/tape
Keyless APINot metered
$0
A developer who wants to see it work before signing up for anything.

Try it with no account. One call every 15s per IP; a 429 with Retry-After marks the edge.

How the meter works

Not metered against an account, because there is no account. It is THROTTLED instead: 1 request every 15 seconds per IP, under a shared daily ceiling across all keyless callers. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a throttled call gets a 429 with Retry-After and a link back here. If the shared daily ceiling is spent, the lane closes to a plain "sign in" - never an error.

GET /v1/domains/:domain (one domain, latest, signed)
Keyed APIMetered
Included with the account
A signed-in DRM3 account, using a key minted for that account.

Included with any account. One call = one unit against a daily budget; past it, DRM3 credits. Never a surprise bill.

How the meter works

ONE request = ONE unit, counted against your account - all of your keys share one allowance. Your included allowance is a DAILY budget that resets at 00:00 UTC, and every metered response carries its own meter in the headers (listed below), so you never have to guess where you stand. Past the included allowance, each request draws DRM3 credits from your account's shared balance (the same credits every DRM3 app uses); when that balance is empty you get an HTTP 402 naming the exhausted axis and where to top up. It never silently drops your data, and there is no surprise overage bill.

/v1/domains/v1/domains/:domain/v1/changes/v1/stream/v1/domains/:domain/provenance
Pay per callMetered
Per call, USDC on Base
A keyless agent that would rather pay than sign up.

Pay per call in USDC on Base, no account. No payment header answers a 402 that lists the price.

How the meter works

Priced per call in USDC on Base. No key and no account: present an X-PAYMENT header, we verify it, settle it on Base, and serve the call only once the payment has actually moved. If settlement does not go through you are not charged and the call is not served. A keyless call with no payment gets a 402 that IS the price menu.

Any /v1/* read except the signed export bundle (exports need a keyed account)
OperatorNot metered
Not available
DomainDrift operators and service keys only.

Operators only. Not for sale; a non-admin key gets a 403.

How the meter works

Not metered, because it is not for sale. Non-admin keys get a 403.

/v1/bq/*/v1/enrich-batch/v1/opt-out/v1/domains (POST)/v1/queue/*
The meter on every keyed response.

A metered call answers with these headers so a client can pace itself without a second round trip. Which subset ships depends on your plan: the daily credit plan carries the credit + daily headers, the legacy plan carries the monthly + daily headers. Reset values are Unix seconds.

X-DomainDrift-UsageRequests counted this month (UTC).
X-DomainDrift-Usage-DayRequests counted today (UTC).
X-DomainDrift-Usage-PeriodThe month bucket, YYYY-MM (UTC).
X-DomainDrift-Daily-AllowanceIncluded requests for today.
X-DomainDrift-Daily-RemainingRequests left today.
X-DomainDrift-Daily-ResetUnix seconds at the next 00:00 UTC, when the daily allowance resets.
X-DomainDrift-Credits-AllowanceDaily credit plan: included DomainDrift credits for today.
X-DomainDrift-Credits-UsedDaily credit plan: DomainDrift credits used today (0.05 per request).
X-DomainDrift-Credits-RemainingDaily credit plan: DomainDrift credits left today.
X-DomainDrift-Credits-ResetDaily credit plan: Unix seconds until credits reset (next 00:00 UTC).
X-DomainDrift-AllowanceLegacy monthly plan: included requests this month.
X-DomainDrift-RemainingLegacy monthly plan: requests left this month.
X-DomainDrift-ResetLegacy monthly plan: Unix seconds until the month resets.
X-DomainDrift-BurstDaily burst multiple in force (1 = your day is your share, no batching).
Never metered:
  • Service + scanner keys (they run the pipeline, they are not a customer).
  • The public web surfaces above (they carry no key at all).
  • Keyless single-domain lookups, which are throttled per IP instead of metered.
  • x402 payers, who already paid for the call at the door.

The web, without an account

The public web surface is a real slice of the product, not a screenshot. Where a list is truncated, DomainDrift shows you the true size of what it is holding back - never a silent cut.

PublicOPEN
  • The landing page, the daily change feed (+ RSS/JSON), and the public analytics pages.
  • The Time Machine for any domain at /t/<domain>: the LATEST signed observation.
  • The embeddable signed badge, universal search, the verifier, and these docs.
  • The TOP 3 of every list - with the true, live total shown next to it.
With a DRM3 accountSIGN IN
  • Every list in full: the catalog, the change wire, services, certificate issuers.
  • Domain detail pages, and ALL point-in-time history / time-series.
  • Exports: CSV, signed evidence bundles, and change alerts.
  • Bring your own: put one of your own domains under watch in a group (paid plans raise the caps).

The x402 lane: settle per request, no account

The standard metered lane is credits on a key (the same meter as everything on this page). This lane exists for an agent that would rather settle a single request than hold an account: call a metered /v1/* endpoint with no key and no X-PAYMENT header, and the response is a 402 whose body IS the price menu. Settle 0.01 USDC on Base (an EIP-3009 transferWithAuthorization, signed client-side), retry the same request with an X-PAYMENT header, and the call is served. No key, no account.

The payment is settled on Base before the response leaves: we reserve your authorization, broadcast it, and serve the call once the USDC has actually moved. If settlement does not go through you are not charged and the call is not served. Public endpoints are never charged. Per-request settlement is the convenience price for skipping signup; a key is the cheap way to volume.

Higher volume

The keyless lane is enough to see it work; it cannot be batched into a bulk pull. For production, sign in with a DRM3 account, mint your own X-DomainDrift-Key, and send it as a header (or Authorization: Bearer). Every metered response carries its own meter in the headers, so you always know where you stand. Bulk exports and the signed per-domain bundle are the metered product.

Get your API key →

Free with a DRM3 account. One key, reusable - rotate it any time from the console.

Open the API console → Read the docs →
CONTINUOUS INTERNET TELEMETRY24H DRIFT4,815 material changesacross 2,911 domains · 24h to ~80m ago · -25,022 vs yesterdayROTATION53 domains moved DNS from koaladns.com to magpiedns.com, 53 moved backa rotation loop, not a migration · 24hNOW593 curated domains not reachablelast probe, steadySITE ERRORS17,426 sites serving errorslast probe · 5xx / 404 / TLSBOT DEFENSEbot defense observed on 79,482 sites429 rate-limit / 403 bot-block, a posture signal