---
title: "Buy domains"
method: POST
path: "/v1/domains/purchases"
tags: ["Domains"]
---

# Buy domains

`POST /v1/domains/purchases`

## Request

- Base URL: `https://api.spacefast.com`
- URL: `https://api.spacefast.com/v1/domains/purchases`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.spacefast.com/v1/auth/oauth2/authorize`, token URL `https://api.spacefast.com/v1/auth/oauth2/token`; client credentials, token URL `https://api.spacefast.com/v1/auth/oauth2/token`, scopes: `domains:write`)

Buys up to 10 registrable apex domains in one checkout. Quotes each, adds it to the team's inventory, and holds them all for one payment. Returns every registration (`pending_payment`) and `data.checkout.url` for a person to open and pay; nothing is registered or charged until they do. One name that can't be bought refuses the whole cart. Pass `expectedTotalCents` (before tax) to refuse if the price moved. A hostname the team already holds is registered on its existing record.

## Request body

- object
  - `domains` object[], required: Domains to buy in one checkout (up to 10).
    - `name` string, required: Registrable apex domain; canonicalized server-side.
    - `period` 1: Years. Only 1 is offered today.
  - `teamId` string: Owning team. Defaults to the active team.
  - `contactId` string, required: Registrant contact (`dcon_...`) from createDomainContact.
  - `expectedTotalCents` integer: Refuse with domain_checkout_total_changed if the live total (before tax, ICANN fees included) differs.

## Response `200`

Response for status 200

- object
  - `$schema` string, uri: Canonical JSON Schema URL for this response body. The server also sends it in the `Link: rel="describedby"` response header.
  - `data` object, required
    - `registrations` object[], required
      - `id` string, nullable, required: Registration or transfer record id; null when unregistered.
      - `domainId` string, required: Domain inventory record (`dom_...`).
      - `hostname` string, required: Registered hostname.
      - `provider` 'dsapi' | 'manual', nullable, required: Wrapped registrar bridge where the registration lives.
      - `status` string, required: Registration lifecycle status. `pending_payment` means checkout is open and nothing is registered yet.
      - `expiresAt` string, date-time, nullable, required: Instant when the registration expires.
      - `redemptionEndsAt` string, date-time, nullable, required: Instant when the redemption window ends after expiry.
      - `autoRenew` boolean, required: Saved auto-renew preference. Nothing renews on its own yet; renew by hand.
      - `transferLock` boolean, required: Whether outbound transfers are locked.
      - `privacySetting` 'enable_privacy_service' | 'redact_contact_info' | 'disclose_contact_info', nullable, required: WHOIS privacy behavior.
      - `contactId` string, nullable, required: Registrant contact record.
      - `failureReason` string, nullable, required: Provider failure detail when status is `failed`.
      - `purchase` object, nullable, required: Money state of the current purchase or renewal line; null when none is in flight.
        - `intentId` string, required: Purchase intent that paid for this line.
        - `lineStatus` 'awaiting_payment' | 'submitting' | 'settled' | 'refunding' | 'refunded' | 'cancelled', required
        - `checkout` object, nullable: Existing open payment link, requested with includeCheckout and returned only to callers authorized to purchase this domain. Null when no open link is available; check checkoutUnavailable for lookup failures. Omitted when not requested or not authorized.
          - `id` string, required: Existing Stripe Checkout session id.
          - `url` string, uri, required: Open this existing checkout to complete payment.
          - `expiresAt` string, date-time, required: When this checkout expires.
        - `checkoutUnavailable` boolean: True when the requested payment link could not be retrieved or verified. Registration status remains available. Retry the read to recover the existing checkout; do not start another purchase.
        - `quotedFeeAmountCents` integer, nullable, required: Registrar fee before tax, in cents.
        - `paidAmountCents` integer, nullable, required: What the customer paid for this line, tax included, in cents.
        - `refund` object, nullable, required
          - `reference` string, required: Stripe refund id.
          - `amountCents` integer, required
          - `refundedAt` string, date-time, required
      - `createdAt` string, date-time, nullable, required
      - `updatedAt` string, date-time, nullable, required
    - `checkout` object, required
      - `id` string, required: Stripe Checkout session id.
      - `url` string, uri, required: Open this to pay. Nothing is charged until payment completes here.
      - `expiresAt` string, date-time, required
      - `subtotalCents` integer, required
      - `currency` 'USD', required
      - `lines` object[], required
        - `domainId` string, required
        - `registrationId` string, required
        - `name` string, required
        - `amountCents` integer, required: Price before tax, in cents: the registrar fee plus any ICANN fee.
  - `operation` object, nullable, required: Always null: nothing runs until payment completes.
    - `id` string, required
    - `kind` string, required
    - `status` 'queued' | 'running' | 'succeeded' | 'failed' | 'canceled', required
    - `resources` object[], required
      - `type` string, required
      - `id` string, required
    - `progress` object
      - `total` integer, required
      - `completed` integer, required
      - `failed` integer, required
    - `diagnostics` object[]
      - `code` string, required: Stable snake_case diagnostic code naming the public contract that produced it.
      - `severity` 'info' | 'warning' | 'error', required: How actionable the diagnostic is.
      - `message` string, required: Human-readable explanation with enough detail to act on.
      - `path` string, nullable: Artifact path the diagnostic points at, for example "_headers:12", when one exists.
      - `provider` 'infra' | 'dns' | 'registrar' | 'runtime', nullable: Upstream system the diagnostic originated from, when not Spacefast itself.
      - `details` object, nullable: Machine-readable context for the diagnostic code.
      - `fix` string, nullable: Concrete, agent-actionable remediation hint, when one can be derived.
      - `retryable` boolean, nullable: Whether retrying the same operation can resolve this diagnostic without the caller changing anything.
    - `createdAt` string, date-time, required
    - `finishedAt` string, date-time

## Other responses

- `default`: Problem details (RFC 9457). Any 4xx/5xx response is one `application/problem+json` document.

---

[API](https://skmtc.dev/spacefast/apis/spacefast-api.md) · [All operations](https://skmtc.dev/spacefast/apis/spacefast-api/llms.txt) · [OpenAPI document](https://skmtc.dev/spacefast/apis/spacefast-api/revisions/bd165bc7c983?raw)
