# Provider credentials (BYOK) (/api-v2/provider-credentials)



A BYOK provider credential lets Zumik call your provider account on your behalf. The raw secret is sealed at rest with AES-256-GCM and a one-way fingerprint is kept for display. The plaintext is never stored unencrypted, logged, or returned on any response. Credential ids are prefixed `pcr_`. See the [BYOK setup guide](/guides/byok-setup).

All requests require a bearer API key. See [authentication](/api-reference/authentication).

## Attach a credential [#attach-a-credential]

`POST /v2/provider-credentials`

<ParamField body="provider" type="string">
  One of `openai`, `anthropic`, `xai`, `google_gemini`, `fireworks_ai`.
</ParamField>

<ParamField body="display_name" type="string">
  A human label for the credential.
</ParamField>

<ParamField body="secret" type="string">
  The raw provider secret. Must not be empty. Sealed at rest and fingerprinted; never returned.
</ParamField>

<ParamField body="metadata" type="object">
  Arbitrary JSON you attach for your own bookkeeping.
</ParamField>

```bash
curl https://api.zumik.ai/v2/provider-credentials \
  -H "Authorization: Bearer $ZUMIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "openai",
    "display_name": "Acme OpenAI prod",
    "secret": "sk-..."
  }'
```

```json
{
  "id": "pcr_01jy7nmn67q9r0s1t2u3v4w5xy",
  "object": "provider_credential",
  "project_id": "prj_01jy7n0a4c8m2t6v9q3wrxk7bd",
  "provider": "openai",
  "status": "active",
  "display_name": "Acme OpenAI prod",
  "secret_fingerprint": "zfp_9a3c1e7b2d4f6a08",
  "created_at": "2026-06-15T16:30:41Z",
  "metadata": {}
}
```

<ResponseField name="id" type="string">
  Opaque credential id, prefixed `pcr_`.
</ResponseField>

<ResponseField name="object" type="string">
  Always `provider_credential`.
</ResponseField>

<ResponseField name="project_id" type="string">
  The owning project.
</ResponseField>

<ResponseField name="provider" type="string">
  The provider, echoed back.
</ResponseField>

<ResponseField name="status" type="string">
  `active`, `disabled`, or `revoked`.
</ResponseField>

<ResponseField name="display_name" type="string">
  The label you supplied.
</ResponseField>

<ResponseField name="secret_fingerprint" type="string">
  A short non-reversible fingerprint, prefixed `zfp_`, so you can recognize the key without it being reconstructable.
</ResponseField>

<ResponseField name="created_at" type="string">
  RFC 3339 creation timestamp.
</ResponseField>

<ResponseField name="metadata" type="object">
  The metadata you supplied.
</ResponseField>

## List credentials [#list-credentials]

`GET /v2/provider-credentials`

```bash
curl https://api.zumik.ai/v2/provider-credentials \
  -H "Authorization: Bearer $ZUMIK_API_KEY"
```

```json
{
  "object": "list",
  "data": [
    {
      "id": "pcr_01jy7nmn67q9r0s1t2u3v4w5xy",
      "object": "provider_credential",
      "provider": "openai",
      "status": "active",
      "display_name": "Acme OpenAI prod",
      "secret_fingerprint": "zfp_9a3c1e7b2d4f6a08"
    }
  ]
}
```

## Rotate a credential [#rotate-a-credential]

`POST /v2/provider-credentials/{credential_id}/rotate`

Replaces the sealed secret in place. The id and any matching stay stable; only the sealed material and fingerprint change, and the status returns to `active`.

<ParamField path="credential_id" type="string">
  The `pcr_...` id to rotate.
</ParamField>

<ParamField body="secret" type="string">
  The replacement secret. Must not be empty.
</ParamField>

```bash
curl -X POST https://api.zumik.ai/v2/provider-credentials/pcr_01jy7nmn67q9r0s1t2u3v4w5xy/rotate \
  -H "Authorization: Bearer $ZUMIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "secret": "sk-new..." }'
```

Returns the updated credential with a new `secret_fingerprint`.

## Delete a credential [#delete-a-credential]

`DELETE /v2/provider-credentials/{credential_id}`

Drops the public credential and its sealed secret together, so nothing lingers at rest.

<ParamField path="credential_id" type="string">
  The `pcr_...` id to delete.
</ParamField>

```bash
curl -X DELETE https://api.zumik.ai/v2/provider-credentials/pcr_01jy7nmn67q9r0s1t2u3v4w5xy \
  -H "Authorization: Bearer $ZUMIK_API_KEY"
```

```json
{
  "id": "pcr_01jy7nmn67q9r0s1t2u3v4w5xy",
  "object": "provider_credential.deleted",
  "deleted": true
}
```

## Errors [#errors]

| Status | Code                    | When                                                  |
| ------ | ----------------------- | ----------------------------------------------------- |
| 400    | `invalid_request_error` | `secret` is empty, or the secret could not be sealed. |
| 401    | `invalid_api_key`       | Missing or invalid API key.                           |
| 404    | `invalid_request_error` | The credential does not exist in this project.        |

See the full table on [errors](/api-reference/errors).
