Developer API
Deterministic domain appraisals, comparable sales, and recorded-sales search over plain HTTPS + JSON. The same engine and corpus that power the site - the same input always returns the same output.
API access is included with paid plans. Calls draw from a monthly API allowance that is separate from the site's appraisal credits, so a large batch through the API does not leave the account without credits on the website.
Quickstart
Create a key under Profile - API keys (shown once, store it securely), then:
curl -X POST https://audit.domains/api/v1/appraise \
-H "Authorization: Bearer ad_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"domain": "example.com"}'Keys are sent as Authorization: Bearer ad_live_... or x-api-key. Requests without a key receive 401 key_required; keys on the free plan receive 402 paid_plan_required.
A successful appraisal returns this shape (values illustrative; fields are contract-locked and the interval always accompanies the point figure):
{
"domain": "example.com",
"valueUSD": 12400,
"valueRange": { "low": 7400, "mid": 12400, "high": 20900 },
"tier": "mid-market",
"confidence": 62,
"factors": [
{ "key": "brandability", "label": "Brandability", "score": 61 },
{ "key": "length", "label": "Length", "score": 74 }
],
"methodologyVersion": "4.14",
"engineVersion": "20.0.0",
"comps": [
{ "domain": "shop.com", "priceUsd": 3500000, "year": "2014",
"venue": "Sedo", "similarity": 82,
"basis": "Shared keyword" }
],
"appraisalHash": "8c1f...e2a9",
"inputCommitment": "b44d...91c7",
"resultDigest": "f01a...77de",
"generatedAt": "2026-08-05T12:00:00.000Z",
"dataEdition": "2026-07-01"
}Endpoints
HEAD /api/v1/comps behaves as GET without a body and still spends 1 API call - do not use it as an uptime probe; poll GET /api/v1/usage or the status page instead. On /api/v1/bulk, each failed domain comes back with its own error code: appraisal_failed (the reserved call is refunded) or quota_exhausted (that domain was never charged).
Every response that reached the meter carries X-Credits-Limit, X-Credits-Remaining and X-Credits-Reset headers reporting your monthly API allowance and the date it refills - that is any 200, and the 402 you get when the allowance is spent. A request rejected before metering carries no meter to report: a malformed body, a missing or unknown key, or a 429 from the per-address limit. Read the meter without spending a call at GET /api/v1/usage.
X-RateLimit-Limit and X-RateLimit-Remaining currently repeat the same monthly allowance figures. Those names conventionally describe a short-window request limiter, which this API now has separately, so they will be redefined to report that limiter instead - not before an announced notice period of at least 30 days. Read X-Credits-* for the allowance meter.
Scopes
Each key is created with a scope. A read key can call the endpoints that spend no credits; a write key can call every endpoint. An endpoint that spends an API call refuses a read key with 403 insufficient_scope, and the scope is checked before the credit is debited, so a refused call costs nothing.
Issue read-scoped keys to anything that only searches recorded sales or polls the allowance at GET /api/v1/usage, so a leaked key from that integration cannot spend the account's monthly API allowance.
Request limits
Each key has a request limit per 60-second window, applied per key rather than per IP address, so several servers sharing one key share one budget and one server behind a shared address is not affected by its neighbours.
| Plan | Requests per minute |
|---|---|
| Plus | 60 |
| Pro | 120 |
| Max | 300 |
Over the limit, calls return 429 rate_limited with a Retry-After header in seconds and an X-RateLimit-Reset header giving the Unix second the window ends. Retry after that point rather than immediately.
Plans and credits
Each paid plan includes a monthly API allowance alongside its site appraisal credits. The two are metered separately: spending one does not spend the other.
| Plan | Price | API calls / mo | Per call | Site credits / mo | Bulk endpoint |
|---|---|---|---|---|---|
| Plus | $39/mo | 500 | $0.078 | 50 appraisals/mo | Included |
| Pro | $129/mo | 2,500 | $0.052 | 250 appraisals/mo | Included |
| Max | $399/mo | 15,000 | $0.027 | 1,500 appraisals/mo | Included |
The free plan does not include API access - keys created on a free account return 402 paid_plan_required until the account upgrades.
When the monthly API allowance is spent, calls return 402 api_quota_exhausted and site appraisal credits are unaffected. Wait for the monthly reset, or move to a larger plan on the pricing page.
Errors
Every failure returns the same JSON shape, and some codes add a field of their own on top of it - plan here. error is the only field to match on; it is stable and a given code always arrives with the same status. retryable says whether repeating the identical request can succeed, and requestId - also sent as the X-Request-Id header on every response, including successes - identifies the call in support requests.
{
"plan": "core",
"error": "api_quota_exhausted",
"message": "This account's monthly API call allowance is spent.",
"detail": "Wait for the monthly reset, or move to a larger plan at https://audit.domains/pricing. Site appraisal credits are a separate allowance and are unaffected.",
"requestId": "8f2a1c4e9b7d0000-LHR",
"docsUrl": "https://audit.domains/developers#api_quota_exhausted",
"retryable": false
}| Status | error | Retry | What to do |
|---|---|---|---|
| 400 | domains_required | no | Include at least one domain in the batch. |
| 400 | invalid_domain | no | Send a registrable hostname such as example.com. |
| 400 | invalid_json | no | Send a JSON body and a Content-Type of application/json. |
| 400 | too_many_domains | no | Split the batch; the per-call maximum is in the max field. |
| 401 | invalid_key | no | Check the key, or create a new one under Profile - API keys. |
| 401 | key_required | no | Send the key as Authorization: Bearer, or as the x-api-key header. |
| 402 | api_quota_exhausted | no | Move to a larger plan or wait for the monthly reset. This is separate from the site's appraisal credits, which are unaffected. |
| 402 | paid_plan_required | no | Upgrade the account; keys on the free plan cannot call the API. |
| 402 | quota_exhausted | no | Wait for the monthly reset, or move to a larger plan. |
| 402 | upgrade_required | no | Move to a plan that includes the feature, such as bulk. |
| 403 | insufficient_scope | no | Endpoints that spend a credit need a write-scoped key; create one. |
| 405 | method_not_allowed | no | Use one of the methods listed in the Allow response header. |
| 429 | rate_limited | yes | Wait the number of seconds in Retry-After, then retry. Do not retry immediately. |
| 500 | appraisal_failed | yes | Retry with backoff; quote the requestId if it persists. |
| 500 | comps_failed | yes | Retry with backoff; quote the requestId if it persists. |
| 500 | sales_unavailable | yes | Retry with backoff; quote the requestId if it persists. |
| 503 | api_auth_unavailable | yes | Retry with backoff. The API refuses rather than serving unmetered. |
| 503 | source_unavailable | no | Use source=verified for the curated corpus. |
Free interactive access for AI assistants
For one interactive question at a time, with no key or API credit, the site runs a hosted MCP server at https://audit.domains/mcp exposing appraise_domain, compare_domains, find_comparable_sales, search_recorded_sales and run_bracket. Recorded-sales search is a citation sample capped at five rows per call. Full row-level research belongs to the paid Sales Research workspace or API. It is rate limited and capped per request; programmatic and bulk volume belongs here on the keyed API. A GET on that URL returns the discovery document with the published limits.
claude mcp add --transport http audit-domains https://audit.domains/mcp
Verifiable by design
Every appraisal response includes its ODVS hashes (appraisalHash, inputCommitment, resultDigest) under the Open Domain Valuation Standard: the same domain on the same engine version always yields the same commitment, and a replay that produces different numbers is provably a determinism violation. The canonicalization scheme is published in the repo's ODVS spec and covered by an independent conformance suite.