> ## 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.

# Managed roles API: list roles and reveal a credential

> List the owner, runtime and read-only logins of a DBHost database with managed SQL roles, and reveal one role's password through the API.

A database with managed SQL roles has three base logins: `owner` for
migrations, `runtime` for your application and `readonly` for reporting. These
endpoints list them and reveal one password at a time. To rotate or revoke a
base role, use [Managed role changes](/api-reference/databases/role-changes).
For additional roles, see [Additional roles on managed databases](/api-reference/databases/custom-roles).
See [Database roles](/guides/database-roles) for the concepts.

API access requires Pro or Business. Both endpoints accept a full-account key
or a key scoped to selected databases that includes this database; see
[Authentication](/api-reference/authentication). Every response, including
errors, is sent with `Cache-Control: no-store`.

## List base roles

```http theme={null}
GET /api/v1/databases/{id}/roles
Authorization: Bearer <api-key>
```

Returns metadata only; no password is included.

```json 200 OK theme={null}
{
  "managed": true,
  "roles": [
    {
      "profile": "owner",
      "username": "dbr_550e8400e29b41d4a716446655440000_own",
      "connectionLimit": 2,
      "generation": 1,
      "credentialGeneration": 1,
      "status": "ready",
      "operationId": null,
      "lastRotatedAt": null
    },
    {
      "profile": "runtime",
      "username": "dbr_550e8400e29b41d4a716446655440000_run",
      "connectionLimit": 4,
      "generation": 1,
      "credentialGeneration": 2,
      "status": "ready",
      "operationId": null,
      "lastRotatedAt": "2026-10-01T09:12:44.000Z"
    },
    {
      "profile": "readonly",
      "username": "dbr_550e8400e29b41d4a716446655440000_read",
      "connectionLimit": 2,
      "generation": 1,
      "credentialGeneration": 1,
      "status": "ready",
      "operationId": null,
      "lastRotatedAt": null
    }
  ]
}
```

A database without managed SQL roles returns `{"managed": false, "roles": []}`.
Roles are always ordered `owner`, `runtime`, `readonly`.

| Field | Description |
| - | - |
| `profile` | `owner`, `runtime` or `readonly` |
| `username` | Generated PostgreSQL login name. The database name is not a username |
| `connectionLimit` | The role's own PostgreSQL connection limit |
| `generation` | Role-set generation for the database |
| `credentialGeneration` | Increases by one each time the password changes |
| `status` | `ready`, `revoked`, `updating` or `expired` |
| `operationId` | ID of the pending role change while `status` is `updating`, otherwise `null` |
| `lastRotatedAt` | Time of the most recent completed rotation, or `null` |

`updating` means a rotation or revocation for that role has not finished; read
it with `GET /api/v1/databases/{id}/role-changes/{operationId}`. `expired`
means the credential's validity period has ended and it can no longer be
revealed.

## Reveal a credential

```http theme={null}
POST /api/v1/databases/{id}/roles/credentials
Authorization: Bearer <api-key>
Content-Type: application/json

{"profile":"runtime"}
```

The body must contain exactly one field, `profile`, set to `owner`, `runtime`
or `readonly`. The role must be `ready`. Each reveal is recorded in the
account's audit log.

```json 200 OK theme={null}
{
  "profile": "runtime",
  "username": "dbr_550e8400e29b41d4a716446655440000_run",
  "connectionLimit": 4,
  "generation": 1,
  "credentialGeneration": 2,
  "status": "ready",
  "host": "db.dbhost.app",
  "port": 6432,
  "database": "my-app",
  "password": "<password>",
  "tlsRequired": true
}
```

Connect with TLS; `tlsRequired` is always `true`. Store the password in a
secret manager and keep it out of logs and source control. A role with a
pending change, a revoked role and an expired role return
`409 MANAGED_ROLE_CONFLICT`.

## Errors

| Status | Code | Description |
| - | - | - |
| 400 | `VALIDATION_ERROR` | Reveal body is not exactly one `profile` field set to `owner`, `runtime` or `readonly` |
| 400 | `INVALID_JSON` | Request body is not valid JSON |
| 401 | `UNAUTHORIZED` | Missing or invalid API key |
| 403 | `PLAN_API_ACCESS_REQUIRED` | API access requires Pro or Business |
| 404 | `DATABASE_NOT_FOUND` | Database doesn't exist, isn't owned by this account or isn't in the key's scope |
| 409 | `MANAGED_ROLE_CONFLICT` | The role is not available in its current state, for example revoked, expired or changing |
| 413 | `PAYLOAD_TOO_LARGE` | Request body is larger than the API limit |
| 429 | `RATE_LIMITED` | Too many requests; retry after the `Retry-After` header |
| 503 | `FEATURE_DISABLED` | Managed roles are temporarily unavailable |
| 503 | `MAINTENANCE` | DBHost is in a maintenance window; retry later |
| 500 | `INTERNAL_ERROR` | The request failed; retry |

## Dashboard

The database detail page shows the same roles and lets you reveal, rotate or
revoke one credential at a time on every plan.


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