# Provider accounts

## What this covers

Your own AI credentials, encrypted per project. A saved account is `configured` until the provider confirms it; only a `verified` account is admitted into an agent pipeline or a call.

Every example below runs as written once these are exported:

```bash
export DVAARIK_API_KEY="dvk_..."        # project API key, server side only
export DVAARIK_TOKEN="<account access token>"   # console session, from POST /console/auth/login
export ACCOUNT_ID="<uuid>"
export PROJECT_ID="<uuid>"
```

A `<value>` inside a JSON body is a value you supply. Responses are JSON; every error body is `{ "detail": … }`. Each schema is expanded once per page, where it first appears.

### Machine door errors

Raised by the project-key dependency before any handler on this page runs.

| Status | Cause |
| --- | --- |
| `401` | `Missing API key` or `Invalid API key` — the `X-Api-Key` header is absent, unknown, or revoked. |
| `403` | `API key is not scoped to a project`, `Project unavailable`, or `API key is missing the required scope '<scope>'`. |
| `429` | The project's `api_rpm` ceiling was exceeded. Honour `Retry-After`; `X-RateLimit-*` headers are on every response. |

Scopes used on this page: `provider_account:read`, `provider_account:write`. Mint a key with only these.

### Account door errors

| Status | Cause |
| --- | --- |
| `401` | No account session was presented, or it is invalid or expired. Refresh once, then re-authenticate. |
| `403` | The account is suspended or its email is not verified. |

## Operations — project API key

Call these from your own server with a project key. Never from a browser or a mobile bundle.

### GET `/v2/provider-accounts`

List the project's saved provider accounts with their verification status. Never credential material.

| Detail | Value |
| --- | --- |
| Door | Project API key — `X-Api-Key: $DVAARIK_API_KEY` |
| Scope | `provider_account:read` |
| Operation | `list_provider_accounts_v2_provider_accounts_get` |
| Success | `200` `ProviderAccountInfo[]` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `include_disconnected` | query | boolean | no |  |
| `limit` | query | integer | no |  |
| `offset` | query | integer | no |  |

#### `ProviderAccountInfo`

Everything safe to return for a saved account. NO credential material — `hint` is a masked fingerprint and is the only echo of the secret.

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `capabilities` | string[] | yes |  |
| `created_at` | date-time | yes |  |
| `hint` | object | yes |  |
| `id` | uuid | yes |  |
| `key_version` | integer | yes |  |
| `last_error` | string or null | yes |  |
| `name` | string | yes |  |
| `project_id` | uuid | yes |  |
| `provider` | string | yes |  |
| `revision` | integer | yes |  |
| `status` | string | yes |  |
| `updated_at` | date-time | yes |  |
| `verified_at` | date-time or null | yes |  |

| Error | When |
| --- | --- |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the machine-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X GET "https://api.developers.dvaarik.com/v2/provider-accounts?limit=20" \
  -H "X-Api-Key: $DVAARIK_API_KEY"
```

### POST `/v2/provider-accounts`

Save an AI credential for this project. It is encrypted at rest and the account starts `configured` — saved, not yet usable.

| Detail | Value |
| --- | --- |
| Door | Project API key — `X-Api-Key: $DVAARIK_API_KEY` |
| Scope | `provider_account:write` |
| Operation | `save_provider_account_v2_provider_accounts_post` |
| Success | `201` `ProviderAccountInfo` |

Request body: `SaveProviderAccountRequest`.

#### `SaveProviderAccountRequest`

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `credentials` | object | yes |  |
| `name` | string | yes |  |
| `provider` | string | yes |  |

| Error | When |
| --- | --- |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the machine-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X POST "https://api.developers.dvaarik.com/v2/provider-accounts" \
  -H "X-Api-Key: $DVAARIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "credentials": {
      "<credential field from the catalogue>": "<secret>"
    },
    "name": "Production account",
    "provider": "<provider id from the catalogue>"
  }'
```

### DELETE `/v2/provider-accounts/{account_id}`

Disconnect the account and forget its credential.

| Detail | Value |
| --- | --- |
| Door | Project API key — `X-Api-Key: $DVAARIK_API_KEY` |
| Scope | `provider_account:write` |
| Operation | `disconnect_provider_account_v2_provider_accounts__account_id__delete` |
| Success | `200` `ProviderAccountInfo` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `account_id` | path | uuid | yes |  |

| Error | When |
| --- | --- |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the machine-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X DELETE "https://api.developers.dvaarik.com/v2/provider-accounts/$ACCOUNT_ID" \
  -H "X-Api-Key: $DVAARIK_API_KEY"
```

### GET `/v2/provider-accounts/{account_id}`

Read one saved account: capabilities, masked hint, status, last error and verification time.

| Detail | Value |
| --- | --- |
| Door | Project API key — `X-Api-Key: $DVAARIK_API_KEY` |
| Scope | `provider_account:read` |
| Operation | `get_provider_account_v2_provider_accounts__account_id__get` |
| Success | `200` `ProviderAccountInfo` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `account_id` | path | uuid | yes |  |

| Error | When |
| --- | --- |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the machine-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X GET "https://api.developers.dvaarik.com/v2/provider-accounts/$ACCOUNT_ID" \
  -H "X-Api-Key: $DVAARIK_API_KEY"
```

### POST `/v2/provider-accounts/{account_id}/probe`

Ask the provider to confirm the stored credential. Confirmed becomes `verified`; rejected becomes `invalid`; a transient provider failure stays `configured`, so an uncertain probe never admits a call.

| Detail | Value |
| --- | --- |
| Door | Project API key — `X-Api-Key: $DVAARIK_API_KEY` |
| Scope | `provider_account:write` |
| Operation | `probe_provider_account_v2_provider_accounts__account_id__probe_post` |
| Success | `200` `ProviderAccountInfo` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `account_id` | path | uuid | yes |  |

| Error | When |
| --- | --- |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the machine-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X POST "https://api.developers.dvaarik.com/v2/provider-accounts/$ACCOUNT_ID/probe" \
  -H "X-Api-Key: $DVAARIK_API_KEY"
```

### POST `/v2/provider-accounts/{account_id}/rotate`

Re-encrypt the stored secret under the current keyring key. The credential itself does not change.

| Detail | Value |
| --- | --- |
| Door | Project API key — `X-Api-Key: $DVAARIK_API_KEY` |
| Scope | `provider_account:write` |
| Operation | `rotate_provider_account_v2_provider_accounts__account_id__rotate_post` |
| Success | `200` `ProviderAccountInfo` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `account_id` | path | uuid | yes |  |

| Error | When |
| --- | --- |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the machine-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X POST "https://api.developers.dvaarik.com/v2/provider-accounts/$ACCOUNT_ID/rotate" \
  -H "X-Api-Key: $DVAARIK_API_KEY"
```

## Operations — account session

The same resource through the console door. These are what the web console calls; both doors return the same shapes.

### GET `/console/v2/projects/{project_id}/provider-accounts`

List the project's saved provider accounts with their verification status. Never credential material.

| Detail | Value |
| --- | --- |
| Door | Account session — `Authorization: Bearer $DVAARIK_TOKEN` |
| Operation | `consoleListProviderAccounts` |
| Success | `200` `ProviderAccountInfo[]` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `project_id` | path | uuid | yes |  |
| `include_disconnected` | query | boolean | no |  |
| `limit` | query | integer | no |  |
| `offset` | query | integer | no |  |

| Error | When |
| --- | --- |
| `401` | No account session was presented, or it is invalid or expired. |
| `403` | The account is suspended or its email is not verified. |
| `404` | The project or the addressed resource does not exist for this owner. A resource owned by another developer is deliberately indistinguishable from one that never existed. |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the account-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X GET "https://api.developers.dvaarik.com/console/v2/projects/$PROJECT_ID/provider-accounts?limit=20" \
  -H "Authorization: Bearer $DVAARIK_TOKEN"
```

### POST `/console/v2/projects/{project_id}/provider-accounts`

Save an AI credential for this project. It is encrypted at rest and the account starts `configured` — saved, not yet usable.

| Detail | Value |
| --- | --- |
| Door | Account session — `Authorization: Bearer $DVAARIK_TOKEN` |
| Operation | `consoleSaveProviderAccount` |
| Success | `201` `ProviderAccountInfo` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `project_id` | path | uuid | yes |  |

Request body: `SaveProviderAccountRequest`.

| Error | When |
| --- | --- |
| `401` | No account session was presented, or it is invalid or expired. |
| `403` | The account is suspended or its email is not verified. |
| `404` | The project or the addressed resource does not exist for this owner. A resource owned by another developer is deliberately indistinguishable from one that never existed. |
| `409` | The project or resource is in a state that refuses this change. |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the account-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X POST "https://api.developers.dvaarik.com/console/v2/projects/$PROJECT_ID/provider-accounts" \
  -H "Authorization: Bearer $DVAARIK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "credentials": {
      "<credential field from the catalogue>": "<secret>"
    },
    "name": "Production account",
    "provider": "<provider id from the catalogue>"
  }'
```

### DELETE `/console/v2/projects/{project_id}/provider-accounts/{account_id}`

Disconnect the account and forget its credential.

| Detail | Value |
| --- | --- |
| Door | Account session — `Authorization: Bearer $DVAARIK_TOKEN` |
| Operation | `consoleDisconnectProviderAccount` |
| Success | `200` `ProviderAccountInfo` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `account_id` | path | uuid | yes |  |
| `project_id` | path | uuid | yes |  |

| Error | When |
| --- | --- |
| `401` | No account session was presented, or it is invalid or expired. |
| `403` | The account is suspended or its email is not verified. |
| `404` | The project or the addressed resource does not exist for this owner. A resource owned by another developer is deliberately indistinguishable from one that never existed. |
| `409` | The project or resource is in a state that refuses this change. |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the account-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X DELETE "https://api.developers.dvaarik.com/console/v2/projects/$PROJECT_ID/provider-accounts/$ACCOUNT_ID" \
  -H "Authorization: Bearer $DVAARIK_TOKEN"
```

### GET `/console/v2/projects/{project_id}/provider-accounts/{account_id}`

Read one saved account: capabilities, masked hint, status, last error and verification time.

| Detail | Value |
| --- | --- |
| Door | Account session — `Authorization: Bearer $DVAARIK_TOKEN` |
| Operation | `consoleGetProviderAccount` |
| Success | `200` `ProviderAccountInfo` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `account_id` | path | uuid | yes |  |
| `project_id` | path | uuid | yes |  |

| Error | When |
| --- | --- |
| `401` | No account session was presented, or it is invalid or expired. |
| `403` | The account is suspended or its email is not verified. |
| `404` | The project or the addressed resource does not exist for this owner. A resource owned by another developer is deliberately indistinguishable from one that never existed. |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the account-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X GET "https://api.developers.dvaarik.com/console/v2/projects/$PROJECT_ID/provider-accounts/$ACCOUNT_ID" \
  -H "Authorization: Bearer $DVAARIK_TOKEN"
```

### POST `/console/v2/projects/{project_id}/provider-accounts/{account_id}/probe`

Ask the provider to confirm the stored credential. Confirmed becomes `verified`; rejected becomes `invalid`; a transient provider failure stays `configured`, so an uncertain probe never admits a call.

| Detail | Value |
| --- | --- |
| Door | Account session — `Authorization: Bearer $DVAARIK_TOKEN` |
| Operation | `consoleProbeProviderAccount` |
| Success | `200` `ProviderAccountInfo` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `account_id` | path | uuid | yes |  |
| `project_id` | path | uuid | yes |  |

| Error | When |
| --- | --- |
| `401` | No account session was presented, or it is invalid or expired. |
| `403` | The account is suspended or its email is not verified. |
| `404` | The project or the addressed resource does not exist for this owner. A resource owned by another developer is deliberately indistinguishable from one that never existed. |
| `409` | The project or resource is in a state that refuses this change. |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the account-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X POST "https://api.developers.dvaarik.com/console/v2/projects/$PROJECT_ID/provider-accounts/$ACCOUNT_ID/probe" \
  -H "Authorization: Bearer $DVAARIK_TOKEN"
```

### POST `/console/v2/projects/{project_id}/provider-accounts/{account_id}/rotate`

Re-encrypt the stored secret under the current keyring key. The credential itself does not change.

| Detail | Value |
| --- | --- |
| Door | Account session — `Authorization: Bearer $DVAARIK_TOKEN` |
| Operation | `consoleRotateProviderAccount` |
| Success | `200` `ProviderAccountInfo` |

| Parameter | In | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `account_id` | path | uuid | yes |  |
| `project_id` | path | uuid | yes |  |

| Error | When |
| --- | --- |
| `401` | No account session was presented, or it is invalid or expired. |
| `403` | The account is suspended or its email is not verified. |
| `404` | The project or the addressed resource does not exist for this owner. A resource owned by another developer is deliberately indistinguishable from one that never existed. |
| `409` | The project or resource is in a state that refuses this change. |
| `422` | The request body or query is not valid. `detail` is an array of `{loc, msg, type}` and `loc` names the offending field. |

Plus the account-door errors above. Full list on the [errors page](/docs/errors).

```bash
curl -sS -X POST "https://api.developers.dvaarik.com/console/v2/projects/$PROJECT_ID/provider-accounts/$ACCOUNT_ID/rotate" \
  -H "Authorization: Bearer $DVAARIK_TOKEN"
```

### GET `/v2/provider-catalog`

The connectable AI providers with their capabilities, credential fields and model ids. Render your form from this, never from a list you copied.

| Detail | Value |
| --- | --- |
| Door | Account session — `Authorization: Bearer $DVAARIK_TOKEN` |
| Operation | `get_provider_catalog_v2_provider_catalog_get` |
| Success | `200` `any` |

```bash
curl -sS -X GET "https://api.developers.dvaarik.com/v2/provider-catalog" \
  -H "Authorization: Bearer $DVAARIK_TOKEN"
```

---

Source: https://developers.dvaarik.com/docs/api/provider-accounts · every page as one file: https://developers.dvaarik.com/docs.md
