Work with this as data
Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/audit-domains:audit-domains-sales-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
OpenAPI Specification
openapi: 3.2.0
info:
title: audit.domains public Sales API
version: 1.3.0
description: 'Deterministic domain appraisals, comparable sales, bulk valuation, and recorded-sales search. Document version 1.3.0. Since 1.3.0, `GET /api/v1/sales` serves only the curated verified corpus; the legacy `source=ledger` research source was retired so no browser-reachable database RPC can bypass the paid row-level research boundary. Since 1.0.0 the surface gained `GET /api/v1/usage`, a per-key request limiter (answered with `Retry-After` and `X-RateLimit-Reset`), and a monthly API call allowance separate from the site''s appraisal credits - reported by the `X-Credits-*` headers and refused with `402 api_quota_exhausted`. The path prefix stays `/v1`: the locked appraisal projection has not changed, key for key. What this document covers: the five key-authenticated paths listed below - `/api/v1/appraise`, `/api/v1/comps`, `/api/v1/bulk`, `/api/v1/usage`, `/api/v1/sales`. One further route exists under the same prefix and is NOT part of the public contract: `/api/v1/historical-sales/snapshots/active` is an internal serving seam for the website''s own comparables snapshot - anonymous, unmetered, edge-cached, does not use the error envelope described here, and may change without a version bump. Do not build against it. No key? A keyless $5 card lane for single appraisals is described in https://audit.domains/api/openapi-machine.json (POST https://audit.domains/api/machine/resolve); it is not part of this contract. API access is included with paid plans: every request requires an `ad_live_` API key (create one at https://audit.domains/profile?tab=api), keys work only on paid plans, and appraisal-producing calls consume the account''s monthly API allowance. That allowance is SEPARATE from the appraisal credits the website meters: spending one does not spend the other, and a large batch through the API leaves the site quota untouched. When it is spent, calls answer `402 api_quota_exhausted` until the monthly reset. `X-Credits-Limit` / `X-Credits-Remaining` / `X-Credits-Reset` response headers report that allowance and the date it refills, on every response that reached the meter (a 200, or a 402 for a spent allowance); requests rejected before metering - a malformed body, a missing key, a per-IP 429 - carry no meter to report, and `GET /api/v1/usage` reads the same figures without spending a call. `X-RateLimit-Limit` / `X-RateLimit-Remaining` currently repeat those credit figures; those names will be redefined to report the per-key request limiter after an announced notice period of at least 30 days. Key scopes: a key is created with `read` or `write` scope. Endpoints that spend an API call (`/appraise`, `/comps`, `/bulk`) require a `write` key and answer `403 insufficient_scope` otherwise; `/sales` and `/usage` accept either. Issue read-scoped keys to anything that only searches recorded sales or polls the allowance, so a leaked key from that integration cannot spend the account''s API allowance. Request limits: two limiters apply, and the tighter one decides. A per-address token bucket runs BEFORE the key is verified and is sized per endpoint - `/appraise` and `/comps` allow a burst of 10 then about 30 requests per minute, `/bulk` a burst of 4 then about 6 per minute, `/sales` and `/usage` a burst of 30 then about 60 per minute. Behind it, each key has a fixed limit per 60-second window, by plan: Plus 60/min, Pro 120/min, Max 300/min. Because the per-address bucket sits in front, one address cannot reach the per-key figure on `/appraise`, `/comps` or `/bulk` at all: on `/appraise` a single address is held near 30/min whatever the plan allows, and the Max figure of 300/min is reachable only by calling from several addresses. Both limiters answer `429 rate_limited` with `Retry-After` (seconds); only the per-key limiter also sends `X-RateLimit-Reset` (Unix seconds), so the presence of that header is what distinguishes the two. Determinism guarantee: the same domain on the same engine version always returns the same result.'
contact:
url: https://audit.domains/contact
termsOfService: https://audit.domains/terms
servers:
- url: https://audit.domains
security:
- bearerKey: []
- headerKey: []
tags:
- name: Sales
description: Recorded domain sales search
paths:
/api/v1/sales:
parameters:
- name: q
in: query
schema:
type: string
description: Substring match on domain (verified source also matches category/venue).
- name: tld
in: query
schema:
type: string
- name: minPrice
in: query
schema:
type: integer
- name: maxPrice
in: query
schema:
type: integer
- name: yearFrom
in: query
schema:
type: integer
- name: yearTo
in: query
schema:
type: integer
- name: venue
in: query
schema:
type: string
- name: sort
in: query
schema:
type: string
enum:
- price
- date
- domain
default: price
- name: dir
in: query
schema:
type: string
enum:
- asc
- desc
default: desc
- name: page
in: query
schema:
type: integer
minimum: 1
default: 1
- name: pageSize
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 50
- name: source
in: query
schema:
type: string
enum:
- verified
default: verified
description: Recorded-sales source. `verified` is the curated, screened corpus used by audit.domains. The legacy `ledger` source is retired and returns 503 source_unavailable.
get:
summary: Search recorded domain sales (spends nothing, read scope; paid plan required)
operationId: searchSales
responses:
'200':
description: One page of curated verified recorded sales, including facets and aggregates over the filtered result set.
headers:
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
X-Credits-Limit:
$ref: '#/components/headers/X-Credits-Limit'
X-Credits-Remaining:
$ref: '#/components/headers/X-Credits-Remaining'
X-Credits-Reset:
$ref: '#/components/headers/X-Credits-Reset'
X-RateLimit-Limit:
$ref: '#/components/headers/X-RateLimit-Limit'
X-RateLimit-Remaining:
$ref: '#/components/headers/X-RateLimit-Remaining'
Link:
description: 'RFC 8288 pagination: present when hasMore is true, carrying rel="next" for the following page. A convenience view of the page/pageSize/hasMore body fields.'
schema:
type: string
content:
application/json:
schema:
type: object
properties:
source:
type: string
enum:
- verified
total:
type: integer
description: Rows matching the filters across all pages.
page:
type: integer
pageSize:
type: integer
hasMore:
type: boolean
rows:
type: array
items:
$ref: '#/components/schemas/SaleRecord'
stats:
type:
- object
- 'null'
description: Aggregates over the whole filtered set, not just this page. null when nothing matched.
properties:
median:
type: number
highest:
type: number
totalValue:
type: number
facets:
type: object
description: Filter values present in the curated verified corpus.
properties:
tlds:
type: array
items:
type: string
years:
type: array
items:
type: integer
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequiredReadOnly'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/SalesUnavailable'
'503':
description: source_unavailable when a retired sales source such as source=ledger is requested, or api_auth_unavailable when key verification is unreachable.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
tags:
- Sales
head:
summary: Same as GET without the body
operationId: headSales
description: HEAD runs the real GET handler and discards the body (RFC 9110). It spends no API call. Status codes and headers are those of GET.
responses:
'200':
description: Headers only, per RFC 9110. The GET handler runs and its status and headers are returned with no body, so every status GET can answer is reachable here too.
headers:
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
X-Credits-Limit:
$ref: '#/components/headers/X-Credits-Limit'
X-Credits-Remaining:
$ref: '#/components/headers/X-Credits-Remaining'
X-Credits-Reset:
$ref: '#/components/headers/X-Credits-Reset'
X-RateLimit-Limit:
$ref: '#/components/headers/X-RateLimit-Limit'
X-RateLimit-Remaining:
$ref: '#/components/headers/X-RateLimit-Remaining'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequiredReadOnly'
'405':
$ref: '#/components/responses/MethodNotAllowed'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/SalesUnavailable'
'503':
description: source_unavailable (the research ledger is not published yet; the body carries `source`) or api_auth_unavailable.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
tags:
- Sales
components:
responses:
SalesUnavailable:
description: 'sales_unavailable - the recorded-sales index could not be read. Retryable: retry with backoff, and quote the requestId if it persists.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: key_required (no key sent) or invalid_key (unknown, revoked, or expired). key_required also carries withoutKey (what works with no key) and plans (what a key costs).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
headers:
WWW-Authenticate:
description: Bearer realm="audit.domains" on key_required; adds error="invalid_token" on invalid_key (RFC 6750).
schema:
type: string
RateLimited:
description: rate_limited - either the per-address token bucket in front of key verification tripped, or the key is over its plan's per-minute limit (Plus 60, Pro 120, Max 300). See the request-limits note in the document description for the per-endpoint per-address figures. Both carry Retry-After; only the per-key limiter carries X-RateLimit-Reset and a `plan` field in the body, so that header is what tells you which limiter refused the call.
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
X-RateLimit-Reset:
description: Unix seconds at which the current 60-second window ends. Present when the per-key limiter tripped.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
PaymentRequiredReadOnly:
description: paid_plan_required - the account is on the free plan, which does not include API access. This endpoint spends no API calls, so it never answers an allowance code.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
MethodNotAllowed:
description: method_not_allowed - this path does not serve that HTTP method. The `Allow` response header and the body's `allowed` array both list the methods it does serve.
headers:
Allow:
description: Comma-separated methods this path serves.
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
headers:
X-Credits-Reset:
description: 'ISO 8601 instant the allowance refills: the first instant of the next UTC month.'
schema:
type: string
format: date-time
X-RateLimit-Limit:
description: Currently repeats X-Credits-Limit. Read X-Credits-Limit for the allowance.
schema:
type: integer
X-Request-Id:
description: Correlation id for this request, on every response including successes. Quote it in support requests.
schema:
type: string
X-Credits-Limit:
description: Monthly API call allowance for this account's plan.
schema:
type: integer
X-RateLimit-Remaining:
description: Currently repeats X-Credits-Remaining. Read X-Credits-Remaining for the allowance.
schema:
type: integer
X-Credits-Remaining:
description: API calls left in the current monthly allowance, after this call.
schema:
type: integer
schemas:
SaleRecord:
type: object
properties:
domain:
type: string
price:
type: number
saleDate:
type: string
description: ISO date, a bare year, or empty when unknown.
venue:
type:
- string
- 'null'
category:
type:
- string
- 'null'
verified:
type: boolean
source:
type: string
description: Corpus provenance. The paid sales API currently serves "curated".
PlanOffer:
type: object
description: One paid plan whose key can call /api/v1, derived from the billing configuration (the same figures as https://audit.domains/pricing).
properties:
id:
type: string
description: Plan id, as /checkout?plan= names it.
name:
type: string
usdPerTerm:
type: number
description: Price of one term in USD.
term:
type: string
enum:
- month
monthlyCalls:
type: integer
description: /api/v1 calls included per term; a separate allowance from site appraisals.
usdPerCall:
type: number
description: Effective USD per included call, rounded to 4 places.
burstPerMinute:
type: integer
description: Per-key request limit per minute.
checkout:
type: string
format: uri
description: Where a person signs in and pays. An agent cannot complete it.
required:
- id
- name
- usdPerTerm
- term
- monthlyCalls
- usdPerCall
- burstPerMinute
- checkout
Error:
type: object
properties:
error:
type: string
description: Stable machine-readable code; the only field a client should match on. The full catalogue is published at https://audit.domains/developers#errors
message:
type: string
description: Human-readable and safe to display; never contains internals.
detail:
type: string
description: The actionable next step, when there is one.
requestId:
type: string
description: Correlation id for this request, always present; also sent as the X-Request-Id header on every response. Quote it in support requests.
docsUrl:
type: string
format: uri
description: Deep link to this code's entry in the published error catalogue.
retryable:
type: boolean
description: Whether repeating the identical request can succeed.
plan:
type: string
description: The account's plan id. Present on the per-key 429 rate_limited, on 403 insufficient_scope, and on the 402 codes.
scope:
type: string
description: The scope the key was created with. Present on 403 insufficient_scope.
requiredScope:
type: string
description: The scope this endpoint needs. Present on 403 insufficient_scope.
max:
type: integer
description: Maximum domains one bulk call accepts. Present on 400 too_many_domains.
allowed:
type: array
items:
type: string
description: Methods this path serves, matching the Allow header. Present on 405 method_not_allowed.
source:
type: string
description: The sales source that is not published. Present on 503 source_unavailable.
withoutKey:
type: array
items:
$ref: '#/components/schemas/FreeRoute'
description: What works with no key. Present on 401 key_required.
plans:
type: array
items:
$ref: '#/components/schemas/PlanOffer'
description: The plans whose keys can call this API, cheapest first. Present on 401 key_required and 402 paid_plan_required.
planTerms:
type: string
description: Whether a paid term renews. Present on 401 key_required.
pricing:
type: string
format: uri
description: The keyless API index, which carries the same plans. Present on 401 key_required.
required:
- error
- message
- requestId
- docsUrl
- retryable
FreeRoute:
type: object
description: A route that works with no key. {name} stands for the domain.
properties:
what:
type: string
how:
type: string
required:
- what
- how
securitySchemes:
bearerKey:
type: http
scheme: bearer
description: 'Authorization: Bearer ad_live_...'
headerKey:
type: apiKey
in: header
name: x-api-key