Reference
View as MarkdownDatabases API
17 operations. Every call needs a session cookie or an Authorization: Bearer nct_… token unless marked Public. Conventions, errors and scopes
/database-enginesList the database engines and versions that can be created
Response 200 · OK · application/json
- EngineView[] | nullrequired
401Unauthorized403Forbidden500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/environments/{environmentId}/databasesCreate a managed database
Creates a staged database service with its data volume and generated credentials; nothing runs until it is deployed. Other services connect with ${{<slug>.DATABASE_URL}} (or REDIS_URL, MONGO_URL).
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
environmentIdrequired | path | string |
Request body · application/json · required
- acceptLicensebooleanRequired for engines with a source-available licence (MongoDB, Redis)
- databaseNamestring
- engineenum: postgres | mysql | mariadb | valkey | redis | mongodb | clickhouserequiredValkey is the default key-value engine
- flavorenum: postgisImage variant, e.g. postgis for PostgreSQL
- namestringDisplay name; defaults to the engine name
- serverIdstring
- versionstringMajor version; omitted means the engine's default
Response 201 · Created · application/json
- appliedGenerationinteger (int64)required
- Configrequired
- createdAtstring (date-time)required
- currentDeploymentIdstringrequired
- ReleaseRefrequired
- desiredStateenum: running | stoppedrequired
- DomainView[] | nullrequired
- environmentIdstringrequired
- generationinteger (int64)required
- GitRefrequired
- gitTokenSetbooleanrequired
- hasStagedChangesbooleanrequired
- idstringrequired
- kindenum: app | worker | database | route | stackrequired
- DeploymentRefrequired
- MaintenanceViewrequired
- namestringrequired
- NetworkRef[] | nullrequired
- ObservedViewrequired
- observedAtstring (date-time) | nullrequired
- PendingChangeCountsrequired
- privateHoststringrequired
- projectIdstringrequired
- registryAuthSetbooleanrequired
- ScalingViewrequired
- ServerRefrequired
- serverIdstringrequired
- slugstringrequired
- sourceTypeenum: image | git | external | composerequired
- stagedKindstring | nullrequirednew | edited | null
- stalebooleanrequired
- TailnetViewrequired
- updatedAtstring (date-time)required
- VolumeRef[] | nullrequired
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/databaseGet a managed database's engine, exports and state
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Response 200 · OK · application/json
- credentialKeysstring[] | nullrequiredVariables that hold credentials; rotate them with the rotate action
- deployedbooleanrequired
- EngineViewrequired
- ExportView[] | nullrequired
- imagestringrequired
- InfoView
- ReplicationView
- RotationView
- serviceIdstringrequired
- Specrequired
- UpgradeView
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/promotePromote a read replica to primary (manual)
Called on the replica. Manual: NebulaCtrl does not detect failures or switch automatically. With dryRun the plan is returned (status 200): switchover while the old primary is reachable (it is frozen, stopped and fenced, the replica replays everything, no data is lost) or forced otherwise (it needs acceptDataLoss: what the replica had not received is lost). The old primary is fenced and never runs as a primary again; rebuild it as a replica or delete it. Variables that reference the old primary are rewritten as staged changes. Production environments need approval. Asynchronous: poll replication.promotion.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serviceIdrequired | path | string |
Request body · application/json · required
- acceptDataLossbooleanRequired for a forced promote: what the replica had not received is lost
- confirmstringMust equal the replica's slug
- dryRunbooleanOnly return the plan
Response 202 · Accepted · application/json
- dryRunbooleanrequired
- PromotePlanrequired
- promotionIdstring
- statusstring
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/public-portGet a database's public port
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Response 200 · OK · application/json
- allowCidrsstring[] | nullrequired
- denyCidrsstring[] | nullrequired
- deployedbooleanrequiredThe proxy publishes the port
- enabledbooleanrequired
- hoststringThe address clients connect to (the server's public IP); empty when the server has none
- listenPortinteger (int64)
- newEntrypointbooleanrequiredThe proxy does not listen on this port yet: applying it recreates the proxy container (about a second of dropped connections)
- openToAllbooleanrequiredThe allow-list admits every address (confirmed with the database slug)
- routeIdstringThe route service that holds the port
- serverIdstring
- serverNamestring
- stagedbooleanrequiredThe route has changes that are not deployed yet
- suggestedPortinteger (int64)requiredA free port to start from when enabling
- tlsenum: passthroughrequiredThe proxy never terminates TLS on this port
- warningsstring[] | nullrequired
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/public-portPublish (or change) a database's public port
Stages a TCP route on listenPort of the database's server with a mandatory IP allow-list and an optional deny list (deny first). 0.0.0.0/0 or ::/0 is accepted only with confirmOpen set to the database slug. The proxy forwards raw TCP and never terminates TLS. Nothing changes until the route is deployed; a new port recreates the proxy container (about a second of dropped connections). Needs projects:write and proxy:write. 422 codes: allowlist_required, open_confirmation_required, invalid_config, invalid_listen_port, no_server, agent_too_old. 409 port_in_use.
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Request body · application/json · required
- allowCidrsstring[] | nullrequiredClient networks (CIDRs or addresses) allowed to connect. Mandatory.
- confirmOpenstringRequired when allowCidrs admits every address (0.0.0.0/0 or ::/0): the database slug
- denyCidrsstring[] | nullClient networks refused first, even when allowCidrs admits them
- listenPortinteger (int64)requiredPort on the server (not 80, 443 or a proxy port)
Response 200 · OK · application/json
- allowCidrsstring[] | nullrequired
- denyCidrsstring[] | nullrequired
- deployedbooleanrequiredThe proxy publishes the port
- enabledbooleanrequired
- hoststringThe address clients connect to (the server's public IP); empty when the server has none
- listenPortinteger (int64)
- newEntrypointbooleanrequiredThe proxy does not listen on this port yet: applying it recreates the proxy container (about a second of dropped connections)
- openToAllbooleanrequiredThe allow-list admits every address (confirmed with the database slug)
- routeIdstringThe route service that holds the port
- serverIdstring
- serverNamestring
- stagedbooleanrequiredThe route has changes that are not deployed yet
- suggestedPortinteger (int64)requiredA free port to start from when enabling
- tlsenum: passthroughrequiredThe proxy never terminates TLS on this port
- warningsstring[] | nullrequired
401Unauthorized403Forbidden404Not Found409Conflictport_in_use422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/public-portClose a database's public port
Deletes the route service. A deployed route disappears from the server's table at once.
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Response 200 · OK · application/json
- allowCidrsstring[] | nullrequired
- denyCidrsstring[] | nullrequired
- deployedbooleanrequiredThe proxy publishes the port
- enabledbooleanrequired
- hoststringThe address clients connect to (the server's public IP); empty when the server has none
- listenPortinteger (int64)
- newEntrypointbooleanrequiredThe proxy does not listen on this port yet: applying it recreates the proxy container (about a second of dropped connections)
- openToAllbooleanrequiredThe allow-list admits every address (confirmed with the database slug)
- routeIdstringThe route service that holds the port
- serverIdstring
- serverNamestring
- stagedbooleanrequiredThe route has changes that are not deployed yet
- suggestedPortinteger (int64)requiredA free port to start from when enabling
- tlsenum: passthroughrequiredThe proxy never terminates TLS on this port
- warningsstring[] | nullrequired
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/public-port/connectionReveal the external connection string (audited)
Like revealDatabaseExport, but with the server's public IP and the public port instead of the private host. Needs deployments:write, is uncached and recorded as secret.reveal. 409 public_port_disabled; 422 no_public_address when the server has no public IP.
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Request body · application/json · required
- keystringOne of the database's exports; defaults to the engine's connection URL (DATABASE_URL, REDIS_URL, MONGO_URL)
Response 200 · OK · application/json
- expiresAtstring (date-time)requiredThe value is meant to be shown for this long only; clients must not persist it
- hoststringrequired
- keystringrequired
- portinteger (int64)required
- revealedAtstring (date-time)required
- valuestringrequired
401Unauthorized403Forbidden404Not Found409Conflictpublic_port_disabled422Unprocessable Entityno_public_address500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/rebuildRebuild a replica, or a fenced old primary as a replica
Clones the primary again into a new data volume (the old volume is kept until it is deleted). On a fenced old primary the body may name the new primary to follow. Asynchronous.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serviceIdrequired | path | string |
Request body · application/json · required
- followServiceIdstringFor a fenced old primary: the new primary to follow (default: the replica that was promoted)
Response 202 · Accepted · application/json
- serviceIdstringrequired
- statusstringrequired
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/refreshAsk the agent for the database's version, size and connections
Asynchronous: poll GET /services/{id}/database (or watch the event feed) for the new info.
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Response 202 · Accepted · application/json
- commandIdstringrequired
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/replicaRemove a read replica
Called on the replica. Deletes its container and data volume, drops its slot, role and pg_hba.conf line on the primary and releases its mesh link. Asynchronous.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serviceIdrequired | path | string |
Response 202 · Accepted · application/json
- serviceIdstringrequired
- statusstringrequired
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/replicasAdd a read replica of a PostgreSQL primary
Creates a read replica service in the primary's environment and clones the primary into it. The replica runs on the primary's server or, with the server mesh enabled on both, on another server. Asynchronous: the replica is pending, then preparing, cloning, deploying and streaming; follow it with GET /services/{id}/database/replication. With dryRun only the plan is returned (status 200). Replication is asynchronous and manual: nothing is detected or switched automatically.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
serviceIdrequired | path | string |
Request body · application/json · required
- acceptMeshChangesbooleanConfirms that the replica adds tailnet devices (a replication link)
- dryRunbooleanOnly return the plan
- namestringDisplay name; defaults to <primary>-replica-<n>
- serverIdstringrequiredThe server the replica runs on (the primary's server, or another server with the mesh enabled)
Response 202 · Accepted · application/json
- dryRunbooleanrequired
- ReplicaPlanrequired
- serviceIdstring
- statusstring
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/replicationGet the read replica group of a PostgreSQL database
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Response 200 · OK · application/json
- canPromotebooleanrequired
- ServiceRef
- PromotionView
- rebuildablebooleanrequiredA replica that can be rebuilt, or a fenced old primary that can be rebuilt as a replica
- ReplicaMemberView[] | nullrequired
- roleenum: standalone | primary | replica | fencedrequired
- ReplicaStateView
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/revealReveal a connection string (audited)
Returns one derived export such as DATABASE_URL in plain text, uncached. Requires the deployments:write scope (or admin) and is recorded in the audit log as secret.reveal. Every other read stays masked.
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Request body · application/json · required
- keystringrequiredOne of the database's exports, e.g. DATABASE_URL
Response 200 · OK · application/json
- expiresAtstring (date-time)requiredThe value is meant to be shown for this long only; clients must not persist it
- keystringrequired
- revealedAtstring (date-time)required
- valuestringrequired
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/rotate-credentialsRotate the database password
Changes the application password inside the running database through the agent (or, for Valkey and Redis, stages a new password), updates the variable and stages every service that references the database. Nothing is deployed. With dryRun only the plan is returned.
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Request body · application/json · required
- dryRunbooleanOnly return the plan
Response 200 · OK · application/json
- commandIdstring
- dryRunbooleanrequired
- RotationPlanrequired
- rotationIdstring
- statusenum: planned | pending | appliedrequired
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/upgradeUpgrade the database version
In-place engines stage the new image. PostgreSQL majors are converted with pg_upgrade into a new volume (the old volume is kept) and the new version is staged when the conversion finishes. Take a backup first.
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Request body · application/json · required
- confirmstringrequiredMust equal the service slug
- targetVersionstringrequired
Response 200 · OK · application/json
- commandIdstring
- UpgradePlanrequired
- statusenum: staged | pendingrequired
- upgradeIdstring
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/services/{serviceId}/database/upgrade/planPlan a version upgrade
| Parameter | In | Type | Description |
|---|---|---|---|
serviceIdrequired | path | string |
Request body · application/json · required
- targetVersionstringrequired
Response 200 · OK · application/json
- blockersstring[] | nullrequired
- downtimestringrequired
- enginestringrequired
- executablebooleanrequired
- fromstringrequired
- helperImagestring
- imagestring
- kindstringrequired
- methodstringrequired
- stepsstring[] | nullrequired
- tostringrequired
- warningsstring[] | nullrequired
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.