---
title: POST /api/keys
description: Mint a new named CLI API key owned by the authenticated user. The raw key is returned exactly once.
---

<Note>

This backs the web **Settings → API keys → create** flow. The OTP flow ([CLI auth](/api-reference/cli-auth)) mints keys too — use that for terminal provisioning.

</Note>

Mints a new named CLI API key owned by the authenticated user. The raw key is returned **exactly once**, here; it is never retrievable again.

## Endpoint

```text
POST https://scripto.codika.io/api/keys
```

## Auth

Session (web).

## Request

| Field | Type | Meaning |
|---|---|---|
| `name` | string | **Required**, ≤ 100 chars. A human-readable label. |

```json
{ "name": "ci-runner" }
```

## Response (201)

```json
{
  "success": true,
  "data": {
    "key": "scripto_…",
    "record": {
      "id": "key_…",
      "name": "ci-runner",
      "prefix": "scripto_",
      "start": "scripto_ab",
      "createdAt": "2026-06-25T14:30:00.000Z",
      "expiresAt": null
    }
  }
}
```

Copy `key` immediately — it won't be shown again.

## Errors

| HTTP | `code` | Cause |
|---|---|---|
| 400 | `invalid-argument` | Missing name, or name > 100 chars. |
| 401 | `unauthenticated` | Not signed in. |
| 500 | `internal` | Backend error. |

## Next

- **[DELETE /api/keys/[id]](/api-reference/revoke-key)** — revoke a key.
- **[API keys](/concepts/api-keys)** — the policy (long-lived, named, revocable).
