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

# vetta keys

> Create, list, rotate, and revoke scoped API keys.

API keys are how CI and services authenticate. Each key carries an explicit scope list, so a deploy key need not be an admin key.

## Commands

| Command | Description |
| - | - |
| `vetta keys create` | Mint a scoped key. The secret is shown once. |
| `vetta keys list` | List keys — metadata only, never secrets. |
| `vetta keys rotate <key-id>` | Mint a replacement secret for a key. |
| `vetta keys revoke <key-id>` | Revoke a key immediately. |

## create

```bash theme={"system"}
vetta keys create --name ci --scopes agents:write,sessions:write,billing:read
```

| Flag | Description |
| - | - |
| `--name` | Human-readable label (required). |
| `--scopes` | Comma-separated scope list (required). |

`--scopes` is validated client-side against the shared scope enum, so an unknown scope fails before the request is sent.

> [!WARNING]
>
> The `secret` in the `create` and `rotate` replies exists nowhere else. It is not stored in retrievable form and no route returns it again. Capture it now or mint another key.

## list

```bash theme={"system"}
vetta keys list --limit 2
```

```json theme={"system"}
{
  "data": [
    {
      "id": "key_gwpjrs1egky00g6vw5gjczj6fs",
      "object": "api_key",
      "name": "ci",
      "prefix": "sk_test_pdme",
      "scopes": ["agents:write", "agents:read", "sessions:write", "billing:read"],
      "created_by": { "type": "key", "id": "key_66nnedy98yfx3ygzssfv99p7tf" },
      "last_used_at": null,
      "created_at": "2026-08-22T23:56:53.464Z"
    }
  ],
  "has_more": true,
  "next_cursor": "key_m3jjzgc4zsffsnqhvwwf28m9d1"
}
```

`prefix` is the 12-character display prefix — the same value `vetta whoami` reports as `key_prefix`, and the only part of a secret that is ever readable. `last_used_at` is `null` for a key that has never authenticated a request, which makes unused keys easy to find:

```bash theme={"system"}
vetta keys list --limit 100 | jq -r '.data[] | select(.last_used_at == null) | .id'
```

| Flag | Description |
| - | - |
| `--limit` | Page size. |
| `--after` | Cursor from a previous page's `next_cursor`. |

## rotate & revoke

```bash theme={"system"}
vetta keys rotate key_gwpjrs1egky00g6vw5gjczj6fs
vetta keys revoke key_gwpjrs1egky00g6vw5gjczj6fs
```

Neither takes a flag; both take the key id as a positional argument.

`rotate` returns a new secret, once. `revoke` takes effect immediately — in-flight requests holding the old secret start failing with `401`. Both actions are recorded in the [audit log](https://vetta.sh/docs/cli/audit.md) as `api_key.rotated` and `api_key.revoked`.

> [!NOTE]
>
> Test-mode keys (`sk_test_…`) run against the no-real-money seam: sessions execute and the ledger moves, but no charge reaches a payment processor. Check `mode` in [`vetta whoami`](https://vetta.sh/docs/cli/auth#whoami) if you are unsure which you hold.


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