Cheapest Domains Tlds API

The Tlds API from Cheapest Domains — 2 operation(s) for tlds.

Operations 2

GET /api/v1/tlds/{tld} Compare prices for an extension #
GET /api/v1/tlds/{tld}/history Get price history for an extension #

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.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/cheapest-domains:cheapest-domains-tlds-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 Specification

cheapest-domains-tlds-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Cheapest Domains public Tlds 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: Tlds
paths:
  /api/v1/tlds/{tld}:
    get:
      operationId: get_tld_prices
      summary: Compare prices for an extension
      description: Compare all covered registrars for one extension. Returns source failures, quote timestamps and minimum terms; availability is not checked.
      security: []
      parameters:
      - name: tld
        in: path
        required: true
        description: One covered ASCII top-level extension, such as com or .com. Multi-part suffixes and IDNs are not covered.
        schema:
          type: string
          pattern: ^\.?[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$
          maxLength: 64
          description: One covered ASCII top-level extension, such as com or .com. Multi-part suffixes and IDNs are not covered.
      - 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: 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:
      - Tlds
  /api/v1/tlds/{tld}/history:
    get:
      operationId: get_price_history
      summary: Get price history for an extension
      description: 'Return how each covered registrar''s renewal or registration price for one extension changed over time: price periods with the date each price was first seen, when the previous price was last seen, and whether it came from our scheduled refreshes or the registrar''s own price page archived by the Internet Archive. A first record may be older than its date. Availability is not checked.'
      security: []
      parameters:
      - name: tld
        in: path
        required: true
        description: One covered ASCII top-level extension, such as com or .com. Multi-part suffixes and IDNs are not covered.
        schema:
          type: string
          pattern: ^\.?[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$
          maxLength: 64
          description: One covered ASCII top-level extension, such as com or .com. Multi-part suffixes and IDNs are not covered.
      - 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: price
        in: query
        required: false
        description: 'Which price history to return: the annual renewal (default) or the first-year registration, which includes promotions.'
        schema:
          type: string
          enum:
          - renewal
          - registration
          default: renewal
          description: 'Which price history to return: the annual renewal (default) or the first-year registration, which includes promotions.'
      - 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/PriceHistory'
            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:
      - Tlds
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
    HistoryStep:
      type: object
      required:
      - from
      - to
      - cents
      - approximate
      - source
      - firstRecord
      properties:
        from:
          type: string
          format: date-time
          description: When this price was first seen.
        to:
          type:
          - string
          - 'null'
          format: date-time
          description: When the next price or a removal was first seen; null while current.
        cents:
          type: integer
          minimum: 0
          description: Integer USD cents; 1000 = USD 10.
        regularCents:
          type: integer
          minimum: 0
          description: Published regular price while this price is a promotion.
        approximate:
          type: boolean
          description: Converted to USD from another currency.
        source:
          enum:
          - refresh
          - archive
          description: 'refresh: our scheduled refresh (since 2026-09-28). archive: the registrar’s own price page as copied by the Internet Archive.'
        changedAfter:
          type: string
          format: date-time
          description: 'The previous price was last seen then: the change happened between this and from.'
        firstRecord:
          type: boolean
          description: No earlier record; the price may be older than from.
        lastConfirmed:
          type: string
          format: date-time
          description: 'Archived prices: the last archived copy still showing this price.'
        archiveUrl:
          type: string
          format: uri
    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.
    PriceHistory:
      allOf:
      - $ref: '#/components/schemas/Envelope'
      - type: object
        required:
        - comparison
        - tld
        - price
        - pageUrl
        - historyStart
        - registrars
        - truncated
        - notes
        properties:
          comparison:
            $ref: '#/components/schemas/Comparison'
          tld:
            type: string
          price:
            enum:
            - renewal
            - registration
          pageUrl:
            type: string
            format: uri
          historyStart:
            type:
            - string
            - 'null'
            format: date-time
          truncated:
            type: boolean
            description: True when only the newest periods fit one response.
          notes:
            type: array
            items:
              type: string
          registrars:
            type: array
            items:
              type: object
              required:
              - registrarId
              - registrarName
              - pageUrl
              - listedNow
              - current
              - changes
              - lowestCents
              - highestCents
              - steps
              properties:
                registrarId:
                  type: string
                registrarName:
                  type: string
                pageUrl:
                  type: string
                  format: uri
                listedNow:
                  type: boolean
                current:
                  type:
                  - object
                  - 'null'
                  description: The current step, with the same fields as steps[]; null when the registrar does not list the extension now.
                changes:
                  type: integer
                  minimum: 0
                lowestCents:
                  type: integer
                  minimum: 0
                  description: Integer USD cents; 1000 = USD 10.
                highestCents:
                  type: integer
                  minimum: 0
                  description: Integer USD cents; 1000 = USD 10.
                steps:
                  type: array
                  items:
                    $ref: '#/components/schemas/HistoryStep'
                pricingBasis:
                  type: string
                  enum:
                  - sampled_standard
                  - sampled_api
                  description: The current saved offer’s sample label, as on price offers; absent for published price lists. Preserve it when quoting the current price.
                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.
                fetchedAt:
                  type:
                  - string
                  - 'null'
                  description: When the current saved offer was retrieved.
    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