> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dbhost.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Additional roles for existing databases

> Opt in an existing database and manage its extra PostgreSQL logins.

Additional roles are available only for an activated account and database.
The existing database owner, connection string and password stay in place.
The API key must have access to the exact database. Responses in this flow
contain role metadata; the credential endpoint is the only exception.

## Opt in and create

Call `POST /api/v1/databases/{databaseId}/legacy-roles/opt-in` with an empty
body. The response contains the overlay ID, generation and `reserved` or
`active` status. Repeating the request for the same database uses the same
overlay. A database outside the activated set is refused.

Call `POST /api/v1/databases/{databaseId}/legacy-roles` with a stable
`Idempotency-Key` header and an exact body:

```json theme={null}
{
  "displayName": "reader",
  "accessProfile": "read_only",
  "connectionLimit": 1
}
```

`accessProfile` is `custom`, `read_only` or `read_write`. A database may have
up to three extra roles; each role has a connection limit from 1 to 20.
`custom` receives no object grants automatically. The response gives a
generated `roleId` and PostgreSQL `username`, never the password. Reuse the
same idempotency key after an uncertain result; changing its choices conflicts.

Call `POST /api/v1/databases/{databaseId}/legacy-roles/{roleId}/prepare`
with an empty body. This prepares the login and returns `sql_ready`. The
database owner must grant `CONNECT` to the generated username if it is not
already granted. Call
`POST /api/v1/databases/{databaseId}/legacy-roles/{roleId}/admit` with an
empty body after the grant. Admission checks the exact role, TLS connection
and grant before returning `ready`. If an agent outcome is uncertain, call
`POST /api/v1/databases/{databaseId}/legacy-roles/{roleId}/reconcile` with
an empty body before retrying another step.

## List, credentials and changes

`GET /api/v1/databases/{databaseId}/legacy-roles` lists metadata only. Use
`?includeRevoked=true` to include roles that have been revoked.

`POST /api/v1/databases/{databaseId}/legacy-roles/{roleId}/credentials`
with an empty body explicitly reveals the ready role's current password. The
response is marked `no-store`; keep the password in a secret store and do not
put it in logs or an application repository. The original owner credential is
never returned by this endpoint.

To rotate or revoke a role, call
`POST /api/v1/databases/{databaseId}/legacy-roles/{roleId}/changes` with a
stable `Idempotency-Key` and `{"kind":"rotate","confirmDisconnect":true}`
or `{"kind":"revoke","confirmDisconnect":true}`. Open sessions may be
disconnected. Read the returned operation via
`GET /api/v1/databases/{databaseId}/legacy-roles/{roleId}/changes/{operationId}`.
For an uncertain outcome, replay the exact change through `POST` at that
operation URL with `{"confirmDisconnect":true}`. Removing a role uses
`DELETE /api/v1/databases/{databaseId}/legacy-roles/{roleId}` and refuses
unresolved dependencies rather than cascading through customer objects.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.