owner, runtime and readonly logins. Each additional role has its own
generated username, password, access profile and connection limit. See
Database roles for the profiles and how to grant a
Custom role access. For a single-login database that opted in to additional
roles, use the additional roles API for existing databases
instead.
API access requires Pro or Business. Every endpoint on this page accepts a
full-account key or a key scoped to selected databases that includes this
database; see Authentication. Every
response, including errors, is sent with Cache-Control: no-store. Only the
credentials endpoint returns a password.
{id} and {roleId} must be lowercase UUIDs. Endpoints that take no body
reject a non-empty body with 400 VALIDATION_ERROR.
The role object
reserved means a create has not finished; see
Reconcile an unfinished create. updating
means a rotation or revocation is pending. expired means the credential’s
validity period has ended; it can no longer be revealed or rotated.
List roles
200 OK
ordinal. Revoked roles are left out unless you add
?includeRevoked=true. Removed roles are never listed.
Create a role
The
Idempotency-Key header is required: 1–200 characters, without line
breaks or NUL characters, and not starting with dbhost-internal-.
A successful create finishes setup in the same call and returns the role as
ready. The response contains no password; use
Reveal the password.
200 OK
CONNECT on the database and can log in immediately.
read_only also gets SELECT and read_write gets DML. A custom role gets
no table grants; grant access from your migrations as the owner role. DBHost
never grants an additional role CREATE or TEMPORARY.
Reuse the same idempotency key after a timeout or an uncertain result. The
same key with the same body returns the same role and resumes its setup; the
same key with a different body returns 409 MANAGED_ROLE_CONFLICT.
Creation is refused with 409 MANAGED_ROLE_CONFLICT when:
- the database already has ten roles. Revoked roles still count; delete one to free its slot
- the display name is already in use
- another role on the database is still
reserved, or a credential change on the database is unfinished - a restore of the database is in progress
- the database is not active
- the database would have four or more additional roles, or the new limit takes the total above the database’s role budget, and the database has no effective server connection cap
CONNECT grant was withdrawn during setup, the response is
409 CONNECT_GRANT_REQUIRED with the SQL the database owner can run, then
retry the same request:
409 Conflict
409 CUSTOM_ROLE_REQUIRES_V3_CLONE. Make a new clone from a newer
backup of the source database before adding roles.
Rename a role
displayName, with the same rules as on
create. Only the label changes; the username, password and grants stay the
same. The role must be ready or revoked.
200 OK
Reveal the password
ready, without a pending change, and not
expired. Each reveal is recorded in the account’s audit log.
200 OK
Rotate or revoke
kind (rotate or revoke) and
confirmDisconnect: true. The Idempotency-Key header follows the same rules
as on create.
rotate sets a new password. revoke disables the login; the role keeps its
slot until you delete it. The role must be ready, and a rotation also needs
an unexpired credential. Changes are refused while a restore of the database
is in progress or another credential change on the database is unfinished.
202 Accepted
202 while status is pending and 200 when it is
completed. credentialGeneration is the generation the change produces.
Retry with the same key and body after an uncertain result; a different
kind on the same key is refused.
Read a change
200 with the same fields as above. It does not advance the change.
Reconcile a change
{"confirmDisconnect": true}. DBHost replays the
recorded change and returns 202 while pending or 200 when completed. A
change that has already completed is not applied again.
Delete a role
{"confirm": true}. A ready role is revoked first,
which closes its open connections, then removed from PostgreSQL. A revoked
role is removed directly. Repeat the same call to continue a pending delete.
DBHost does not cascade through your objects. If the role still owns objects
or holds grants, the role stays revoked and the response lists what to clean
up:
409 Conflict
kind is grant, owned_object, policy, other or other_database. At
most 20 entries are returned; truncated: true means there are more. Revoke
the grants or reassign the objects as the owner role, then call delete again.
Remove a revoked role
revoked and returns
200 with {"roleId": "...", "status": "removed"}, or 202 with
{"roleId": "...", "status": "pending"} while removal runs. Remaining
dependencies return 409 ROLE_DEPENDENCIES without the list; use the
/delete endpoint above to see it.
Reconcile an unfinished create
A create that was interrupted can leave a role inreserved. Retrying the
original create with the same idempotency key and body is the simplest way to
finish it. The two step endpoints are also available. Both take no body.
POST /api/v1/databases/{id}/custom-roles/{roleId}/prepare creates the
PostgreSQL role and returns 202:
202 Accepted
POST /api/v1/databases/{id}/custom-roles/{roleId}/admit applies the
profile’s grants and opens the login. It returns 200 with the same fields
and "status": "ready", or 409 CONNECT_GRANT_REQUIRED with grantSql as
shown under Create a role. Neither step is needed after a
successful create.
Errors
Dashboard and CLI
The same actions are on the database detail page under Additional roles on every plan. The CLI provides them asdbhost managed custom-* commands;
see CLI.