---
title: "Register (or rotate) the caller's own Snowflake Cortex Agent PAT."
method: PUT
path: "/v1/agent/credential"
tags: ["agent"]
---

# Register (or rotate) the caller's own Snowflake Cortex Agent PAT.

`PUT /v1/agent/credential`

## Request

- Base URL: `http://localhost:8080`
- URL: `http://localhost:8080/v1/agent/credential`
- Auth: one of:
  - API key in cookie `dvt_session`
  - HTTP bearer

Forwards the raw Programmatic Access Token to the engine broker to envelope-encrypt (ADR-0082 D2) and stores only the returned ciphertext — the PAT itself is never logged, echoed, or persisted by dvt. `accountLocator` identifies which Snowflake account the PAT belongs to; re-registering the same `accountLocator` rotates the credential in place and clears any prior revocation.

## Request body

- object
  - `accountLocator` string, required: The Snowflake account this PAT authenticates against.
  - `pat` string, required: The raw Programmatic Access Token. Never stored in plaintext.
  - `expiresAt` string, date-time, required: Must be in the future — dvt is TOLD the PAT's expiry, not shown it (ADR-0082 D2b).

## Response `200`

Registered.

- object
  - `data` AgentCredentialStatus: Whether the caller has a live Snowflake Cortex Agent PAT registered (DVT-3518, ADR-0082). Never carries the credential itself.
    - `connected` boolean, required
    - `accountLocator` string: Present only when connected.
    - `expiresAt` string, date-time: Present only when connected.
    - `identity` 'caller': ADDITIVE (DVT-3961, ADR-0082 D2d.4). Present and `"caller"` only in snowflake mode under `DVT_AGENT_IDENTITY=caller` — there `connected` is unconditionally `true` for any authenticated actor (the ingress caller token IS the credential; this response never resolves a stored PAT row). Absent in every other configuration, including snowflake mode's (pre-DVT-3961, still-supported) `DVT_AGENT_IDENTITY=pat` default — those responses are byte-identical to before this field existed.
  - `meta` Meta: Response metadata.
    - `requestId` string, required: Correlates with the X-Request-Id header.
    - `total` integer: Item count, present on collection responses.
    - `nextCursor` string, nullable: Opaque keyset-pagination cursor, present on paginated responses (e.g. GET /v1/dashboards) when more rows exist beyond this page. Pass it back as the `cursor` query param to fetch the next page; absent or null on the last page.
    - `roleResolveDegraded` boolean: Snowflake mode only (DVT-2260), on GET /v1/dashboards: present and true when the caller's live Snowflake role resolution failed or was unavailable — role-shared dashboards may be missing from this page. Omitted (not merely false) whenever resolution succeeded or the role-share arm does not apply (off snowflake mode, an org admin/owner, or off the ingress listener).

## Other responses

- `400`: Malformed request.
- `401`: Missing, invalid, or expired session.
- `403`: `https://docs.dvt.dev/errors/not-in-edition` — snowflake mode under `DVT_AGENT_IDENTITY=caller` only (DVT-3961, ADR-0082 Option A): `editionCapabilities.agentCredentialsCrud` is false there, so per-user agent-PAT registration is unavailable — the ingress caller token IS the credential, so there is nothing to register. Manage agent access via Snowflake roles/grants instead.
- `502`: The analytics engine could not be reached (`https://docs.dvt.dev/errors/engine-unavailable`) or returned an error (`https://docs.dvt.dev/errors/engine-error`). One 502 on this shape is NOT an engine fault and says so: when Snowflake refuses the caller's-rights LOGIN, the Problem type is `https://docs.dvt.dev/errors/caller-connect-refused` — no session was established and the caller's SQL was never reached, so the remediation is a fresh dvt session rather than the engine logs (DVT-4345).
- `503`: The service or a required dependency is temporarily unavailable.

---

[API](https://skmtc.dev/dvt/apis/dvt-rest-api.md) · [All operations](https://skmtc.dev/dvt/apis/dvt-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/dvt/apis/dvt-rest-api/revisions/00016f504165?raw)
