Attach purchased domain
POSThttps://api.instacloud.com/projects/{projectId}/domains/{domainName}/attach
Token scope: account · org · project — read-only tokens refused (not a GET).
Point one hostname of a bought domain at a compute service of this project. Gated — deploy.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
projectId | path | string | yes | |
domainName | path | string | yes |
Request body
application/json
| Field | Type | Required | Description |
|---|---|---|---|
hostname | string | no | the domain itself or any subdomain of it (default: the domain and its www) |
branch | string | no | branch name (default branch if omitted) |
group | string | no | compute service (default: the branch's sole compute service) |
Responses
200
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
domainName | string | yes | |
status | "registered" | "attaching" | "active" | "attach_failed" | "detached" | yes | detached: every service its hostnames named is gone — attach it again |
hostnames | object[] | yes | |
hostnames.hostname | string | yes | |
hostnames.state | "pending" | "attached" | "active" | "failed" | yes | |
hostnames.reason | string | no | |
hostnames.service | string | null | yes | the compute service this hostname serves; each hostname of a domain can serve a different one |
registeredAt | string | null | yes | |
expiresAt | string | null | yes | |
autorenew | boolean | yes | |
privacy | boolean | yes | |
locked | boolean | yes | the registrar transfer lock: while it is on, no other registrar can pull the domain away. Turn it off to move the domain out. What the last write reported, or what registration asked for — nothing reads it back |
nameservers | string[] | yes | what the registrar holds. Empty means never written — only a nameserver write fills it in |
delegated | boolean | yes | the zone is answered by nameservers InstaCloud cannot write to (custody `foreign`), so nothing published resolves and an attach is refused. A MANAGED delegation reads false: the platform still publishes there |
custody | "registrar" | "managed" | "foreign" | yes | who answers the domain's zone: the registrar's own nameservers, a managed InstaCloud zone (delegated, still platform-published), or somewhere the platform cannot write |
transferLockExpiresAt | string | null | yes | ICANN 60-day lock after registration: no transfer out before this, whatever `locked` says |
orderId | string | null | yes |
202
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
status | "approval_required" | no | |
approvalId | string | no | |
action | string | no | the gated action, or a comma-joined compound set — prefer `actions` |
actions | string[] | no | every capability this approval covers |
message | string | no | |
url | string | no | the console page where a project admin reviews this request |
nextActions | object[] | no | |
nextActions.op | string | yes | Neutral logical action id, e.g. "service.add" — NOT an operationId or a CLI/MCP tool name; each client maps it to its own surface. |
nextActions.reason | string | yes | Natural-language, human/LLM-facing "why do this now". |
nextActions.args | object | no | Suggested, flat named arguments; "<placeholder>"s where a value is unknown. |
nextActions.gated | boolean | no | True if the action passes a governance gate. |
403
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
error | string | yes |
404
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
error | string | yes |
409
the hostnames already serve this service, a previous move or sweep has not landed, or the domain is delegated to nameservers outside the registrar
| Field | Type | Required | Description |
|---|---|---|---|
error | string | yes |
503
Default Response
| Field | Type | Required | Description |
|---|---|---|---|
error | string | yes |