Domain purchase and renewal
Covers 10 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 (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}/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.
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.
Sending the same request again is safe: a completed purchase returns 200, and a purchase that was interrupted resumes from where it stopped.
operationId purchaseDomain
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | Domain already purchased (idempotent) | Domain |
| 201 | Purchase complete | Domain |
| 400 | — | — |
| 402 | payment_failed — the payment was declined | Error |
| 403 | — | — |
| 409 | domain_taken·domain_unavailable | 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 | 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.
operationId renewDomain
Request body: application/json · object
| Status code | Description | Response body |
|---|---|---|
| 200 | Renewed domain | Domain |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
POST /v1/orgs/{orgSlug}/domains/{name}/auto-renew
Requires admin or higher. Auto-renewal at the registrar stays on regardless — a domain is lost if its renewal is a day late, so Runlot renews first and bills afterwards. Turning this setting off is not a cancellation, and the UI should say so.
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 | — | — |