# keys

> Create, roll and revoke your test and live API keys.

Create, roll and revoke the API keys your servers use to call Vestra. Use test keys while you build, and live keys for real users. Each key has scopes that limit what it can do, so a key that can only set things up can never act for a user.

## TypeScript

```ts
// Check your key. See your company, this key, and whether it is test or live.
const me = await vestra.keys.me();
console.log(me.org.name, me.mode);

// Create a key for CI. This one can only set things up. Its secret is shown only once.
const ci = await vestra.keys.create({ name: 'ci', scopes: ['setup'] });
console.log(ci.secret);

// Roll a key. You get a new secret, and the old one keeps working for an hour.
const rolled = await vestra.keys.roll(ci.id, { grace_seconds: 3600 });
console.log(rolled.key.secret);

// List your keys. The list shows only the last four characters of each.
const keys = await vestra.keys.list();
console.log(keys.data.map((k) => k.last4));

// Revoke a key. It stops working at once.
await vestra.keys.revoke(ci.id);
```

## Python

```python
# Check your key. See your company, this key, and whether it is test or live.
me = vestra.keys.me()
print(me.org.name, me.mode)

# Create a key for CI. This one can only set things up. Its secret is shown only once.
ci = vestra.keys.create(name="ci", scopes=["setup"])
print(ci.secret)

# Roll a key. You get a new secret, and the old one keeps working for an hour.
rolled = vestra.keys.roll(ci.id, grace_seconds=3600)
print(rolled.key.secret)

# List your keys. The list shows only the last four characters of each.
print([k.last4 for k in vestra.keys.list().data])

# Revoke a key. It stops working at once.
vestra.keys.revoke(ci.id)
```

## CLI

```bash
# List your keys.
vestra keys

# Create a key for CI. This one can only set things up. Its secret is shown only once.
vestra keys create --name ci --scopes setup

# Roll a key. You get a new secret, and the old one keeps working for an hour.
vestra keys roll key_8sd --grace 3600

# Revoke a key. It stops working at once.
vestra keys revoke key_8sd
```

## HTTP

```bash
# Check your key. See your company, this key, and whether it is test or live.
curl "$VESTRA_BASE_URL/v1/me" \
  -H "Authorization: Bearer $VESTRA_API_KEY"

# Create a key for CI. This one can only set things up. Its secret is shown only once.
curl "$VESTRA_BASE_URL/v1/keys" \
  -H "Authorization: Bearer $VESTRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "ci", "scopes": ["setup"] }'

# Roll a key. You get a new secret, and the old one keeps working for an hour.
curl "$VESTRA_BASE_URL/v1/keys/key_3vd/roll" \
  -H "Authorization: Bearer $VESTRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "grace_seconds": 3600 }'

# Revoke a key. It stops working at once.
curl -X DELETE "$VESTRA_BASE_URL/v1/keys/key_3vd" \
  -H "Authorization: Bearer $VESTRA_API_KEY"
```

## MCP

Only people manage keys: no MCP tool creates, rolls or revokes one. Use the console, the CLI or HTTP.

## Good to know

### Scopes

A key's scope is `all`, the default, or any of these: `runtime` (ask, answer, events, files, sessions, connect, memory, routines), `setup` (deployments, tests, secrets, webhooks) and `admin` (keys, limits, your company's settings, and exporting or erasing a user). A key without the scope a route needs gets `403 scope_missing`. Every route in these docs names the scope it needs.

### Test and live

A key's prefix shows its mode: `vk_test_` or `vk_live_`. A new key gets the same mode as the key that created it. A test key only sees test users, test deployments and test money.

### Checking a key

Any key can call `GET /v1/me`, whatever its scopes. It returns your company, the key and its mode.

### Rolling a key

A new key's secret is shown only once. When you roll a key, the old one keeps working for the grace period you choose, or for a day if you choose none.

## The routes behind keys

- `GET` [/v1/me](https://vestra.ai/developers/reference/api/account/get-v1-me.md): Who is calling: the company, the key, and whether it is test or live. Any key may call it.
- `GET` [/v1/org](https://vestra.ai/developers/reference/api/account/get-v1-org.md): The company account: name, status, the wallet in billed dollars, day and month caps, alert thresholds, allowed return URLs, allowed embed origins, default deployment. Key scope: `admin` (or `all`).
- `PATCH` [/v1/org](https://vestra.ai/developers/reference/api/account/patch-v1-org.md): Change the name, allowed return URLs, allowed embed origins, default deployment or default memory mode. Key scope: `admin` (or `all`).
- `GET` [/v1/keys](https://vestra.ai/developers/reference/api/account/get-v1-keys.md): List keys. Only the last four characters are ever shown again. Key scope: `admin` (or `all`).
- `POST` [/v1/keys](https://vestra.ai/developers/reference/api/account/post-v1-keys.md): Create a test or live key. The full key is shown once. Key scope: `admin` (or `all`).
- `POST` [/v1/keys/{key_id}/roll](https://vestra.ai/developers/reference/api/account/post-v1-keys-key-id-roll.md): Replace a key. The old one keeps working for a grace period you choose, then stops. Key scope: `admin` (or `all`).
- `DELETE` [/v1/keys/{key_id}](https://vestra.ai/developers/reference/api/account/delete-v1-keys-key-id.md): Revoke a key immediately. Key scope: `admin` (or `all`).
- `GET` [/v1/audit-log](https://vestra.ai/developers/reference/api/account/get-v1-audit-log.md): Every key use, settings change and approval answer, newest first. Key scope: `admin` (or `all`).
- `GET` [/v1/models](https://vestra.ai/developers/reference/api/account/get-v1-models.md): The models a deployment may choose from. Key scope: `runtime` (or `all`).
- `GET` [/v1/health](https://vestra.ai/developers/reference/api/account/get-v1-health.md): Is the API up. No key needed.
- `GET` [/v1/openapi.json](https://vestra.ai/developers/reference/api/contract/get-v1-openapi-json.md): The whole contract, machine-readable.

Next: [`secrets`](https://vestra.ai/developers/secrets.md)
