Domain purchase and renewal
Covers 12 API operations in the domains category.
| Method | Path | Description |
|---|---|---|
| GET | /v1/orgs/{orgSlug}/domains | Org's domains (runlot domains list) |
| POST | /v1/orgs/{orgSlug}/domains | Buy a domain (runlot domains buy) |
| POST | /v1/orgs/{orgSlug}/domains/check | Look up a domain name (runlot domains check) |
| POST | /v1/orgs/{orgSlug}/domains/import | Import a domain you own (runlot domains import) |
| GET | /v1/orgs/{orgSlug}/domains/{name} | Domain information and recent change history (runlot domains show) |
| POST | /v1/orgs/{orgSlug}/domains/{name}/renew | Renews a domain now (runlot domains renew) |
| POST | /v1/orgs/{orgSlug}/domains/{name}/auto-renew | Changes the auto-renew preference |
| POST | /v1/orgs/{orgSlug}/domains/{name}/lock | Turns the transfer lock on and off (runlot domains lock|unlock) |
| POST | /v1/orgs/{orgSlug}/domains/{name}/auth-code | Checks the transfer auth code (runlot domains auth-code) |
| POST | /v1/orgs/{orgSlug}/domains/{name}/sync | Re-reads this domain from the registrar now (runlot domains sync) |
| GET | /v1/orgs/{orgSlug}/domain-charges | Domain payments, newest first (the latest 50) |
| GET | /v1/orgs/{orgSlug}/domain-charges/{chargeId} | One domain payment — what a 202 from purchase or renewal is followed with |
GET /v1/orgs/{orgSlug}/domains
Requires viewer or higher.
operationId listDomains
| Status code | Description | Response body |
|---|---|---|
| 200 | List | DomainList |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core — the service is temporarily unavailable | Error |
POST /v1/orgs/{orgSlug}/domains
Requires admin or higher — this spends money. Audited as domain.purchase; the
contact details are not retained in the audit log.
Payment comes first. With a saved payment method the price is charged at once
and the request waits for the registration: 201 with the domain. Without one —
or with checkout: true — the answer is 202 with a checkoutUrl; the domain is
registered once that checkout is paid, and GET /domain-charges/{chargeId} follows
it. If the registrar refuses after payment, the payment is refunded in full. While
the registrar is in sandbox mode nothing is registered and nothing is charged.
Paying also agrees to automatic renewal: one year at the registrar's renewal price is charged to the saved payment method 30 days before expiry (retried 7 days and 1 day before) until auto-renew is turned off.
Right after registration the domain's nameservers are set to Runlot's
(ns1~3.runlot.app), so no separate ownership verification is needed and you can
connect an app immediately. ICANN's verification email is sent to the contact
address — tell the customer before they register.
operationId purchaseDomain
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 201 | Paid and registered | Domain |
| 202 | Payment is on its way: status: checkout carries the checkoutUrl to pay in; any other status is a charge still settling. Follow it with getDomainCharge. | DomainCharge |
| 400 | — | — |
| 402 | payment_failed — the saved card was declined. Retry with checkout: true. | Error |
| 403 | — | — |
| 409 | domain_taken·domain_owned·domain_unavailable·domain_premium·purchase_in_progress | Error |
| 422 | registrar_rejected — the registrar rejected the values you sent (contact details and so on). Nothing was registered, and retrying the same request will not help. Submit a new request with corrected input. | Error |
| 502 | saga_incomplete, registrar_error — the purchase is incomplete; sending the same request again continues where it left off. Only failures a retry can fix are reported here. A 502 body may be replaced by the CDN's own HTML page, so browser clients may not see code. | Error |
| 503 | no_core·registrar_not_configured·dns_not_configured·domain_billing_off | Error |
POST /v1/orgs/{orgSlug}/domains/check
Requires member or higher, because this call queries the registrar directly.
priceCents covers the first year of registration, and renewalCents
covers one renewal year. They are reported separately because first-year
discounts are common.
operationId checkDomains
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | Availability by name | object |
| 400 | — | — |
| 403 | — | — |
| 503 | no_core·registrar_not_configured | Error |
POST /v1/orgs/{orgSlug}/domains/import
Requires admin or higher. Audited as domain.import. This does not contact the
registrar — it creates a zone. Once you point the domain's nameservers at
ns1~3.runlot.app at your own registrar, Runlot manages its DNS from then on.
operationId importDomain
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | Domain already imported (idempotent) | Domain |
| 201 | Import complete | Domain |
| 400 | — | — |
| 403 | — | — |
| 409 | domain_taken | Error |
| 503 | no_core·dns_not_configured | Error |
GET /v1/orgs/{orgSlug}/domains/{name}
Requires viewer or higher. A name from another org returns 404.
operationId getDomain
| Status code | Description | Response body |
|---|---|---|
| 200 | Domain | DomainDetail |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/domains/{name}/renew
Requires admin or higher. Audited as domain.renew. Paid the same way as a purchase:
a saved payment method is charged and the request waits for the renewal (200);
otherwise 202 with a checkout. Automatic renewal does not need this call.
operationId renewDomain
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | Paid and renewed | Domain |
| 202 | Payment is on its way — see purchaseDomain | DomainCharge |
| 400 | — | — |
| 402 | payment_failed — the saved card was declined | Error |
| 403 | — | — |
| 404 | — | — |
| 409 | renewal_in_progress·domain_not_ready | Error |
POST /v1/orgs/{orgSlug}/domains/{name}/auto-renew
Requires admin or higher. On: one year is charged to the saved payment method 30 days before expiry (retried 7 days and 1 day before) and the domain is renewed. Off: nothing is charged, the registrar's own auto-renew is turned off too, and the domain lapses at expiry unless it is renewed by hand.
operationId setDomainAutoRenew
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | The domain that changed | Domain |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/domains/{name}/lock
Requires admin or higher. Audited as domain.lock.
operationId setDomainLock
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | The domain that changed | Domain |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/domains/{name}/auth-code
Requires admin or higher. Audited as domain.auth_code — the code itself is never
written to the audit log, because anyone holding it can transfer the domain away.
You can request the code at any time. The only thing that can delay a transfer is ICANN's 60-day lock after a registration or a previous transfer.
operationId getDomainAuthCode
| Status code | Description | Response body |
|---|---|---|
| 200 | Code | object |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/domains/{name}/sync
Requires member or higher. The registrar is the source of truth for the
expiry date, transfer lock, and nameservers. If the registrar reports
that the domain is no longer held by Runlot, its status becomes
transferred_out — the signal that a transfer has completed.
operationId syncDomain
| Status code | Description | Response body |
|---|---|---|
| 200 | The matched domain | Domain |
| 403 | — | — |
| 404 | — | — |
GET /v1/orgs/{orgSlug}/domain-charges
Requires member or higher. Registrations and renewals, paid or not.
operationId listDomainCharges
| Status code | Description | Response body |
|---|---|---|
| 200 | Charges | object |
| 403 | — | — |
GET /v1/orgs/{orgSlug}/domain-charges/{chargeId}
Requires member or higher.
operationId getDomainCharge
| Status code | Description | Response body |
|---|---|---|
| 200 | The charge | DomainCharge |
| 403 | — | — |
| 404 | — | — |