---
title: "Create API key"
method: POST
path: "/api/api-keys/"
tags: ["api-keys"]
---

# Create API key

`POST /api/api-keys/`

Creates a new API key for the current user

## Request body

- APIKeyCreateRequest — Create a key with an explicit action/library scope. The scope fields are required: a request must state both which actions the key may perform and which libraries it covers; omitting either is a 422, never a silent full-access grant. Full access is still expressible, but only explicitly: `actions=[read, write, delete, delete_permanently]` plus `library_scope_mode=all_libraries`.
  - `name` string, required — Descriptive name identifying this API key
  - `actions` GrantAction[], required — Action verbs the key may perform (at least one). `read` is required whenever any broader action is selected. Pass all four actions for a full-access key.
  - `library_scope_mode` 'all_libraries' | 'selected_libraries', required — Which of the owner's libraries a credential covers. `all_libraries` means all current and future live libraries owned by the user. `selected_libraries` means only explicitly selected libraries, with no automatic expansion.
  - `library_ids` string[], nullable — Libraries the key covers. Required (at least one) when `library_scope_mode` is `selected_libraries`; not allowed otherwise. Up to 200 ids.

## Response `201`

Successful Response

- APIKeyCreateResponse — Response when creating a new API key - includes the actual key value. This is the only time the raw API key is exposed. After creation, only the hashed version is stored and the raw key cannot be retrieved.
  - `id` string, required — Unique API key identifier with 'apikey_' prefix
  - `name` string, nullable — Optional descriptive name for this API key
  - `created_at` string, date-time, required — When this API key was created
  - `last_used_at` string, date-time, nullable — When this API key was last used for authentication
  - `is_active` boolean, required — Whether this API key is currently valid and can be used
  - `actions` GrantAction[], nullable — Action verbs this key's grant allows; null for legacy keys
  - `library_scope_mode` 'all_libraries' | 'selected_libraries' — Which of the owner's libraries a credential covers. `all_libraries` means all current and future live libraries owned by the user. `selected_libraries` means only explicitly selected libraries, with no automatic expansion.
  - `selected_library_count` integer, nullable — Number of libraries a 'selected_libraries' grant covers; null unless library_scope_mode is 'selected_libraries'
  - `api_key` string, required — The actual API key value - store this securely as it cannot be retrieved later

## Other responses

- `401` — Missing, invalid, or expired credentials.
- `403` — The credentials are valid but not authorized for this operation — for example an API key whose action or library scope excludes it, or a credential type this operation does not accept.
- `422` — Validation Error
- `429` — Rate limit exceeded. Retry after the interval in the `Retry-After` header.

---

[API](https://skmtc.net/gumnut-ai/apis/gumnut-api.md) · [All operations](https://skmtc.net/gumnut-ai/apis/gumnut-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/gumnut-ai/gumnut-api/versions/e71db45f5d4a/schema)
