Skip to main content
New Use the domain registration API when you want to buy a new domain programmatically through Bizzy. The API searches registrar availability, returns a live quote, charges your account’s default saved Stripe payment method, and starts a registration operation you can poll until it completes. Availability reflects what you can buy, not merely what is unclaimed: a name comes back as available only when the registration that follows would go through.

Prerequisites

Before you call the registration endpoints, make sure you have:
  • A Bizzy API key with domains:read and domains:write.
  • A default Stripe payment method saved on the Bizzy account.
  • The registrant contact details required by the domain registry.
  • A maximum price, in cents, that you are willing to pay for the registration.
  • The business’s acceptance of the domain agreements. An owner or admin accepts them once in Bizzy (the Domain Services Addendum, the registrar’s registration agreement and the registry policies for the ending); an API key can’t. Until then, registration and renewal calls return DOMAIN_AGREEMENTS_REQUIRED with the page where they complete it.
The examples below use this base URL:

Step 1: Search availability

Search the exact domain you want to register.
The response is wrapped in data:
Each result has one of two statuses:
  • status: "ok" means the name was checked. The result includes available, premium, registrationPriceCents, and renewalPriceCents. The prices are in USD cents and are null when the name is unavailable. An unavailable result is taken or cannot be registered, such as a premium-priced name while premium registrations are not offered; premium identifies the latter. Only continue when status is ok and available is true.
  • status: "unsupported_tld" means the name was not checked because its ending is not currently offered. This result contains only status and domain:
For an ok result, registrationPriceCents is the all-in first-year price and renewalPriceCents is the all-in per-year renewal price. They can differ — premium domains in particular often renew at a different price than they register at.

Step 2: Get a live quote

Request a quote for the domain and registration period. periodYears is optional and defaults to 1; it can be any integer from 1 to 10.
Use the returned amountCents as the minimum value for maxAmountCents in the registration request. A premium-priced name fails the quote with PREMIUM_DOMAIN_NOT_SUPPORTED (422) — premium names can’t currently be registered, and nothing is ever charged for them. Search already reports such a name as unavailable, so quoting one directly is the main way to see this error.
amountCents is the all-in total you’ll be charged: the first year at registrationPriceCents plus each additional year at renewalPriceCents. There are no other fees — WHOIS privacy is included at no extra cost.
Quotes are live. The registration request re-checks availability and price before charging. If the current price is higher than maxAmountCents, the API rejects the request instead of charging you.

Step 3: Register the domain

Submit the registration request with the domain, price guardrail, registration settings, and registrant contact details. Registration moves money, so it requires an Idempotency-Key header. Generate a unique value per registration attempt and send the same value if you retry that attempt.
Successful registration requests return 202 Accepted with an operation ID:
The API charges the account’s default saved Stripe payment method before the operation is queued. If no default payment method exists, the request fails with 402.

Idempotency

The Idempotency-Key header is required and makes the charge safe to retry:
  • Reuse the same key to retry a request that may already have succeeded (a timeout or dropped connection before you saw the 202). The API replays the original operation and never charges twice.
  • Use a new key for a genuinely new registration attempt — for example, after a previous attempt failed and was refunded.
If you omit the header, the request is rejected with 400. The same header is required on domain renewal (POST /v1/domains/{id}/registration/renew). A retry must resend the identical request; a same-key request carrying a different body returns 422 with IDEMPOTENCY_KEY_REUSED, and one sent while the original is still running returns 409. See Idempotency for the behavior shared with other POST endpoints.

Required registration inputs

WHOIS privacy is always enabled and isn’t a request field. Transfer lock is enabled automatically after a domain is registered; manage it afterwards with PATCH /v1/domains/{id}/registration. While a transfer to another registrar is under way, a request that sets transferLock returns 409 with REGISTERED_DOMAIN_TRANSFER_IN_FLIGHT. The contact object requires: These contact fields are optional: label, organizationName, jobTitle, and address2 — except on .ai, .co, .io, and .me, whose registries require organizationName. Omitting it there fails with CONTACT_ORGANIZATION_REQUIRED before anything is charged; registrants without a company conventionally use their own full name. If you provide organizationName, jobTitle is also required — the domain registry rejects a company contact without a job title. label is stored only in Bizzy; changing it later does not update the registrar contact. After registration, update registrar-backed contact fields with PATCH /v1/domains/{id}/registration/contact (where the domain’s registration supports contact changes — otherwise the request returns 422 with REGISTRAR_UNSUPPORTED_OPERATION). Changing the registrant’s name, organization, or email restarts ICANN registrant email verification, and is refused with 409 and REGISTERED_DOMAIN_TRANSFER_IN_FLIGHT while a transfer to another registrar is under way for any domain using the contact. Changing only the local label does not contact the registrar or restart verification. For registered domains, wait until the status is expired, then remove the remaining DNS records, email records included. Only the zone’s built-in apex NS and SOA records can remain. A queued or running renewal, or a transfer already under way, also blocks deletion. These refusals return 409 with code REGISTERED_DOMAIN_NOT_EXPIRED, REGISTERED_DOMAIN_RENEWAL_IN_FLIGHT, REGISTERED_DOMAIN_TRANSFER_IN_FLIGHT, or REGISTERED_DOMAIN_DNS_NOT_EMPTY; the last lists the blocking records in the error details.

Sending subdomains

Add a sending subdomain under a verified domain with POST /v1/domains/{id}/subdomains. Send the full name, exactly one label under the parent (mail.example.com under example.com), and an optional purpose: general (the default) sends and receives mail; transactional and marketing send only. The subdomain is active at once — it inherits the parent’s verification, so there is no TXT record to publish. GET /v1/domains lists apex domains only. List a domain’s subdomains with GET /v1/domains/{id}/subdomains, read one with GET /v1/domains/{id}, and remove one with DELETE /v1/domains/{id}/subdomains/{subdomainId}. Every domain response carries kind (apex or subdomain), parentDomainId, and purpose. POST /v1/domains always creates an apex domain with its own verification, whatever the name’s label count. A name one label under a domain you already have returns 409 with code DOMAIN_PARENT_EXISTS and the parent’s id in details.parentDomainId — add it as a subdomain instead. A name deeper under a domain you have, or under one of your subdomains, returns 409 with code DOMAIN_NESTING_UNSUPPORTED: subdomains sit exactly one label under an apex domain, so that name cannot be added while its parent is in your account. Remove all subdomains before deleting their parent with DELETE /v1/domains/{id}, or before requesting a transfer to another registrar. A refusal returns 409 with code DOMAIN_SUBDOMAINS_EXIST and names the subdomains to remove. You cannot add subdomains while a transfer is in progress.

Step 4: Poll the operation

Registration is asynchronous because it depends on payment, registrar, DNS, and email setup work. Poll the operation until it reaches succeeded or failed.
Operation statuses are: When the operation succeeds, resourceType is domain and resourceId is the new Bizzy domain ID.

Step 5: Read the domain

After the operation succeeds, fetch the new domain using resourceId.
Registered domains are managed by Bizzy, so DNS and email authentication records are configured automatically. The domain becomes usable for Bizzy-hosted email after setup completes.

Common failures

Next steps

After registration succeeds:
Last modified on September 27, 2026