runlot
ReferenceAPI

Domain purchase and renewal

Covers 10 API operations in the domains category.

MethodPathDescription
GET/v1/orgs/{orgSlug}/domainsOrg's domains (runlot domains list)
POST/v1/orgs/{orgSlug}/domainsBuy a domain (runlot domains buy)
POST/v1/orgs/{orgSlug}/domains/checkLook up a domain name (runlot domains check)
POST/v1/orgs/{orgSlug}/domains/importImport 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}/renewRenews it (runlot domains renew)
POST/v1/orgs/{orgSlug}/domains/{name}/auto-renewChanges the auto-renew preference
POST/v1/orgs/{orgSlug}/domains/{name}/lockTurns the transfer lock on and off (runlot domains lock|unlock)
POST/v1/orgs/{orgSlug}/domains/{name}/auth-codeChecks the transfer auth code (runlot domains auth-code)
POST/v1/orgs/{orgSlug}/domains/{name}/syncThe registrar reads this again right now

GET /v1/orgs/{orgSlug}/domains

Requires viewer or higher.

operationId listDomains

Status codeDescriptionResponse body
200ListDomainList
403
404
503no_core — cp-public started without cp-coreError

POST /v1/orgs/{orgSlug}/domains

admin and above — this spends money. Audited as domain.purchase (the contact is not retained: audit logs cannot be deleted, and the contact is personal data).

Right after registration, the NS is set to Runlot's nameservers (ns1~3.runlot.app). This means no ownership verification step is needed, and the app can be connected right after purchase. The ICANN verification email goes to the contact address: the screen must disclose this before registration (§5.5).

Sending the same request again is safe. For a completed domain, it returns 200, and a purchase interrupted midway resumes from the step where it stopped.

operationId purchaseDomain

Request body: application/json · object

Status codeDescriptionResponse body
200Domain already purchased (idempotent)Domain
201Purchase completeDomain
400
402payment_failed — the payment was declinedError
403
409domain_taken·domain_unavailableError
422registrar_rejected — the registrar rejected the request values (contact info, and so on). The registration did not go through, and retrying does not help. A request with corrected input must be a new row.Error
502saga_incomplete, registrar_error — resending continues where it left off. The edge (Cloudflare) replaces the body of a 502 with its own HTML — browser clients do not receive code. The server does not send failures here that retrying cannot fix.Error
503no_core·registrar_not_configured·dns_not_configuredError

POST /v1/orgs/{orgSlug}/domains/check

Requires member or higher. Not viewer, because this single call hits the registrar API — it looks like a read, but it goes outbound.

priceCents covers the first year of registration, and renewalCents covers one renewal year. They are separate because first-year discounts are common.

operationId checkDomains

Request body: application/json · object

Status codeDescriptionResponse body
200Availability by nameobject
400
403
503no_core·registrar_not_configuredError

POST /v1/orgs/{orgSlug}/domains/import

Requires admin or higher. Audited as domain.import. This does not call the registrar — it creates a zone, and once the customer changes the NS records to ns1~3.runlot.app at their own registrar, full DNS management becomes ours from that point on (§5.6).

operationId importDomain

Request body: application/json · object

Status codeDescriptionResponse body
200Domain already imported (idempotent)Domain
201Import completeDomain
400
403
409domain_takenError
503no_core·dns_not_configuredError

GET /v1/orgs/{orgSlug}/domains/{name}

Requires viewer or higher. A name from another org returns 404.

operationId getDomain

Status codeDescriptionResponse body
200DomainDomainDetail
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 codeDescriptionResponse body
200Renewed domainDomain
400
403
404

POST /v1/orgs/{orgSlug}/domains/{name}/auto-renew

Requires admin or higher. Auto-renewal on the registrar side stays on (§5.4) — a domain is an asset you lose if you're a day late, so we renew first and bill afterward. The UI must state this alongside it: otherwise the customer turns this off here and believes they have "canceled".

operationId setDomainAutoRenew

Request body: application/json · object

Status codeDescriptionResponse body
200The domain that changedDomain
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 codeDescriptionResponse body
200The domain that changedDomain
400
403
404

POST /v1/orgs/{orgSlug}/domains/{name}/auth-code

Requires admin or higher. Audited as domain.auth_codethe code itself is not stored in the audit log: whoever holds the code can take the domain, and audit entries cannot be deleted.

The way out is open immediately (§5.5). The only thing that can block it is ICANN's 60-day registration/transfer lock, and that is informational.

operationId getDomainAuthCode

Status codeDescriptionResponse body
200Codeobject
403
404

POST /v1/orgs/{orgSlug}/domains/{name}/sync

Requires member or higher. The registrar is the source of truth for expiry date, lock, and NS. If the registrar responds that it is not in our account, that is transferred_out — the only signal that a transfer has completed.

operationId syncDomain

Status codeDescriptionResponse body
200The matched domainDomain
403
404

On this page