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.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/cheapest-domains:cheapest-domains-prices-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
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: 3.2.0
info:
title: Cheapest Domains public Prices API
version: 1.13.0
description: Lowest standard prices among connected registrars with saved offers matching the query, including labeled samples and labeled registrar API rates; offers that couldn’t be refreshed for a day stay, with their age, until a newer catalog replaces them. Coverage is not the whole market. Public GET-only research access, no authentication. Exact-name availability has a separate provider-scoped endpoint. No purchase, renewal, transfer, or account operations. Query current prices instead of relying on remembered values.
servers:
- url: https://www.cheapest.domains
security: []
tags:
- name: Prices
paths:
/api/v1/prices:
get:
operationId: search_prices
summary: Compare renewal prices
description: Compare standard prices, including explicitly labeled Cloudflare samples. Find affordable domain extensions and registrar offers, sorted by annual renewal by default. Saved offers stay listed after a failed refresh, with stale flags and source timestamps for stating their age. Returns prices, citation links, timestamps, coverage, and pagination. Does not check exact-name availability.
security: []
parameters:
- name: q
in: query
required: false
description: 'TLD search: .com is exact; com is partial. Separate alternatives with commas or spaces.'
schema:
type: string
maxLength: 200
description: 'TLD search: .com is exact; com is partial. Separate alternatives with commas or spaces.'
default: ''
- name: registrar
in: query
required: false
description: Connected registrar ID from the registrars endpoint. Omit to compare all.
schema:
type: string
maxLength: 40
pattern: ^[a-z0-9-]+$
description: Connected registrar ID from the registrars endpoint. Omit to compare all.
- name: registrars
in: query
required: false
description: Comma-separated connected registrar IDs to compare together. Use instead of registrar. Cheapest-per-extension winners are chosen within this set.
schema:
type: string
maxLength: 200
pattern: ^[a-z0-9-]+(?:,[a-z0-9-]+)*$
description: Comma-separated connected registrar IDs to compare together. Use instead of registrar. Cheapest-per-extension winners are chosen within this set.
- name: favorites
in: query
required: false
description: Up to two distinct connected registrar IDs, comma-separated. Adds saved favorite offers and fresh baselines for this result page, independent of filters. Does not save preferences or check names.
schema:
type: string
maxLength: 81
pattern: ^[a-z0-9-]+(?:,[a-z0-9-]+)?$
description: Up to two distinct connected registrar IDs, comma-separated. Adds saved favorite offers and fresh baselines for this result page, independent of filters. Does not save preferences or check names.
- name: sort
in: query
required: false
description: Ranking metric. Total uses a conservative new-registration estimate.
schema:
type: string
enum:
- renewal
- registration
- total
default: renewal
description: Ranking metric. Total uses a conservative new-registration estimate.
- name: orderBy
in: query
required: false
description: Order results by the selected price metric or extension. Cheapest-per-extension winners are selected before ordering.
schema:
type: string
enum:
- price
- extension
default: price
description: Order results by the selected price metric or extension. Cheapest-per-extension winners are selected before ordering.
- name: direction
in: query
required: false
description: Ascending or descending result order. Unknown totals follow priced totals in either price direction.
schema:
type: string
enum:
- asc
- desc
default: asc
description: Ascending or descending result order. Unknown totals follow priced totals in either price direction.
- name: years
in: query
required: false
description: Planning horizon in years, including initial registration.
schema:
type: integer
minimum: 1
maximum: 10
default: 3
description: Planning horizon in years, including initial registration.
- name: maxRenewalCents
in: query
required: false
description: Maximum annual renewal in integer USD cents; 1000 means USD 10.
schema:
type: integer
minimum: 0
maximum: 100000000
description: Maximum annual renewal in integer USD cents; 1000 means USD 10.
- name: hideCountryCodes
in: query
required: false
description: Exclude two-letter country-code extensions.
schema:
type: boolean
default: false
description: Exclude two-letter country-code extensions.
- name: hideJumps
in: query
required: false
description: Exclude current renewal prices greater than twice registration.
schema:
type: boolean
default: false
description: Exclude current renewal prices greater than twice registration.
- name: view
in: query
required: false
description: Best returns one winner per TLD; all returns every matching registrar offer.
schema:
type: string
enum:
- best
- all
default: best
description: Best returns one winner per TLD; all returns every matching registrar offer.
- name: includeStale
in: query
required: false
description: Accepted for compatibility. Saved prices stay in results until a successful refresh replaces them and are labeled stale. includeStale=true still requires view=all.
schema:
type: boolean
default: false
description: Accepted for compatibility. Saved prices stay in results until a successful refresh replaces them and are labeled stale. includeStale=true still requires view=all.
- name: limit
in: query
required: false
description: Maximum number of results, up to 200.
schema:
type: integer
minimum: 1
maximum: 200
default: 50
description: Maximum number of results, up to 200.
- name: offset
in: query
required: false
description: Result offset. Follow pagination.next for additional results; the feed can change between requests.
schema:
type: integer
minimum: 0
maximum: 100000
default: 0
description: Result offset. Follow pagination.next for additional results; the feed can change between requests.
- name: name
in: query
required: false
description: One ASCII domain label without the extension, such as myproject. Price and link tools only build links from it; availability and popularity tools send the exact domain to their providers.
schema:
type: string
pattern: ^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$
maxLength: 63
description: One ASCII domain label without the extension, such as myproject. Price and link tools only build links from it; availability and popularity tools send the exact domain to their providers.
- name: format
in: query
required: false
description: Response representation. CSV and Markdown use the same filters, order and bounded pagination; they contain main offers, not favorite comparison arrays. MCP retains structured JSON alongside rendered text.
schema:
type: string
enum:
- json
- csv
- markdown
default: json
description: Response representation. CSV and Markdown use the same filters, order and bounded pagination; they contain main offers, not favorite comparison arrays. MCP retains structured JSON alongside rendered text.
responses:
'200':
description: Success. Inspect coverage, stale flags, minimum terms and pagination.
content:
application/json:
schema:
$ref: '#/components/schemas/Prices'
text/csv:
schema:
type: string
text/markdown:
schema:
type: string
'400':
description: Invalid, repeated, unknown, or incompatible parameters.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Endpoint, covered TLD, or connected registrar not found. Not a domain availability result.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: 'Request budget or concurrency limit reached. Anonymous calls spend weighted read units: 120 units/minute (burst 30) and 3,000/UTC day per network bucket, within a shared 600/minute (burst 120) and 30,000/UTC-day site-wide cap. Price searches rank the whole saved catalog and cost 10 units each; extension, registrar-coverage, estimate and registrar-link endpoints read one extension or source metadata and cost 1 unit, like other requests. Responses served from the CDN cache spend nothing. Each availability or popularity lookup spends 1 unit more plus one lookup from a separate allowance of 10 lookups/minute (burst 4), 300/UTC day and 3,000 per aligned 32-day window. Shared networks can share a bucket, and provider concurrency limits can also answer 429. Wait for the Retry-After seconds before retrying; do not poll.'
headers:
Retry-After:
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'503':
description: Fresh pricing unavailable. Retry after 60 seconds; inspect registrar coverage.
headers:
Retry-After:
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
tags:
- Prices
components:
schemas:
ServiceInformation:
type: object
required:
- name
- url
- setupUrl
- pluginUrl
description: Cheapest Domains identity and optional setup links, separate from upstream evidence. Does not establish client installation or provider health.
properties:
name:
const: Cheapest Domains
url:
type: string
format: uri
setupUrl:
type: string
format: uri
pluginUrl:
type: string
format: uri
Destination:
type: object
required:
- href
- mode
- domain
properties:
href:
type: string
format: uri
mode:
type: string
enum:
- search
- copy
- pricing
domain:
type: string
Comparison:
type: object
required:
- url
- omittedParameters
description: Revisit current standard prices with supported website filters. Omits proposed names and API pagination; does not save prices or availability.
properties:
url:
type: string
format: uri
omittedParameters:
type: array
items:
enum:
- years
- favorites
description: Estimate horizons outside 2, 3, 5 and 10 years use the website default. Favorites are browser-local preferences and are never written by a link. Disclose omitted settings.
Coverage:
type: object
required:
- scope
- totalOffers
- freshOffers
- sources
- notCompared
- partial
properties:
scope:
type: string
totalOffers:
type: integer
freshOffers:
type: integer
partial:
type: boolean
error:
type:
- string
- 'null'
sources:
type: array
items:
$ref: '#/components/schemas/Source'
notCompared:
type: array
items:
type: object
properties:
name:
type: string
url:
type: string
reason:
type: string
Offer:
type: object
required:
- tld
- registrarId
- registrarName
- currency
- registrationCents
- renewalCents
- minimumTermYears
- stale
- estimatedTotalCents
- estimateYears
- availability
- pageUrl
- sourceUrl
- registrarSearch
properties:
tld:
type: string
registrarId:
type: string
registrarName:
type: string
currency:
const: USD
registrationCents:
type: integer
minimum: 0
description: Integer USD cents; 1000 = USD 10.
renewalCents:
type: integer
minimum: 0
description: Integer USD cents; 1000 = USD 10.
minimumTermYears:
type: integer
minimum: 1
countryCode:
type: boolean
sourceUrl:
type: string
format: uri
fetchedAt:
type:
- string
- 'null'
nextRefreshAt:
type:
- string
- 'null'
description: When the saved catalog is due for its next scheduled refresh; not an expiry of its prices.
stale:
type: boolean
description: True when the source’s last refresh failed and its saved catalog is at least 24 hours old. Passing nextRefreshAt alone does not make prices stale; a scheduled refresh every 15 minutes replaces due catalogs.
estimatedTotalCents:
type:
- integer
- 'null'
description: Null for multi-year minimum terms; not zero.
estimateYears:
type: integer
minimum: 1
maximum: 10
default: 3
description: Planning horizon in years, including initial registration.
availability:
const: not_checked
pageUrl:
type: string
format: uri
registrarSearch:
$ref: '#/components/schemas/Destination'
futureRenewalCents:
type: integer
minimum: 0
description: Integer USD cents; 1000 = USD 10.
futureRenewalDate:
type: string
regularRenewalCents:
type: integer
minimum: 0
description: Integer USD cents; 1000 = USD 10.
regularRegistrationCents:
type: integer
minimum: 0
description: Integer USD cents; 1000 = USD 10.
transferCents:
type: integer
minimum: 0
description: Integer USD cents; 1000 = USD 10.
registrationTermCents:
type: integer
minimum: 0
description: Integer USD cents; 1000 = USD 10.
renewalTermCents:
type: integer
minimum: 0
description: Integer USD cents; 1000 = USD 10.
pricingBasis:
type: string
enum:
- sampled_standard
- sampled_api
description: 'Absent for published price lists. sampled_standard: standard-tier prices sampled from registrar search results (Cloudflare). sampled_api (API 1.9.0): registrar API purchase and auto-renewal rates sampled with a synthetic name (GoDaddy); the registrar website and manual renewals can charge more. Both have limited coverage and are not exact-name quotes. Preserve this distinction when displaying or reusing prices.'
originalCurrency:
type: string
originalRegistrationCents:
type: integer
originalRenewalCents:
type: integer
exchangeRate:
type: number
exchangeRateDate:
type: string
exchangeRateSourceUrl:
type: string
billingCountry:
type: string
taxExcluded:
type: boolean
priceValidUntil:
type: string
format: date-time
description: When a scheduled price change takes effect or the exchange rate behind a converted price expires; recheck after this time.
renewalSince:
type: string
format: date-time
description: 'API 1.12.0: when this renewal price (with its regular price) was first seen; unchanged since. Absent when not yet dated. See renewalSinceFirstRecord and the price history endpoint.'
renewalSinceFirstRecord:
type: boolean
description: True when renewalSince is our earliest record of this price, so the price may be older. Say "unchanged since at least" that date.
Source:
type: object
required:
- id
- name
- url
- offerCount
- freshOfferCount
- stale
- refreshing
properties:
id:
type: string
name:
type: string
url:
type: string
format: uri
note:
type: string
offerCount:
type: integer
freshOfferCount:
type: integer
fetchedAt:
type:
- string
- 'null'
nextRefreshAt:
type:
- string
- 'null'
description: When the saved catalog is due for its next scheduled refresh; not an expiry of its prices.
stale:
type: boolean
description: True when the source’s last refresh failed and its saved catalog is at least 24 hours old. Passing nextRefreshAt alone does not make prices stale; a scheduled refresh every 15 minutes replaces due catalogs.
refreshing:
type: boolean
error:
type:
- string
- 'null'
refresh:
type: object
required:
- phase
- completed
- total
- startedAt
- resumeAt
description: Progress of a staged catalog refresh, when one exists. Saved prices remain usable meanwhile.
properties:
phase:
enum:
- queued
- running
- waiting
- paused
- complete
completed:
type: integer
minimum: 0
total:
type: integer
minimum: 0
startedAt:
type: integer
description: Unix time in milliseconds.
resumeAt:
type: integer
description: Unix time in milliseconds.
Error:
type: object
required:
- apiVersion
- error
properties:
apiVersion:
type: string
error:
type: object
required:
- code
- message
properties:
code:
type: string
message:
type: string
retryAfterSeconds:
type: number
minimum: 0
Envelope:
type: object
required:
- service
- apiVersion
- generatedAt
- currency
- coverage
- limits
properties:
service:
$ref: '#/components/schemas/ServiceInformation'
apiVersion:
type: string
generatedAt:
type: string
format: date-time
currency:
const: USD
availability:
const: not_checked
coverage:
$ref: '#/components/schemas/Coverage'
limits:
type: array
items:
type: string
Prices:
allOf:
- $ref: '#/components/schemas/Envelope'
- type: object
required:
- comparison
- offers
- query
- pagination
properties:
comparison:
$ref: '#/components/schemas/Comparison'
offers:
type: array
maxItems: 200
items:
$ref: '#/components/schemas/Offer'
favoriteOffers:
type: array
maxItems: 400
description: Only requested favorites for this page’s extensions, independent of filters. Missing offers are absent; stale offers remain labeled.
items:
allOf:
- $ref: '#/components/schemas/Offer'
- type: object
properties:
differenceFromCheapestCents:
type:
- integer
- 'null'
description: Selected metric minus the lowest fresh quote across all connected registrars. Null for stale/unpriced quotes or absent fresh baseline; never claim savings from stale data.
favoriteBaselines:
type: array
maxItems: 200
items:
$ref: '#/components/schemas/Offer'
description: Lowest fresh saved quote per returned extension for the selected metric, independent of filters. Omitted where no fresh priced baseline exists.
query:
type: object
pagination:
type: object
required:
- limit
- offset
- total
- next
properties:
limit:
type: integer
offset:
type: integer
total:
type: integer
next:
type:
- string
- 'null'
externalDocs:
description: Human and AI integration guide
url: https://www.cheapest.domains/developers