---
title: "Create Api Key"
method: POST
path: "/v1/api-keys"
---

# Create Api Key

`POST /v1/api-keys`

## Request

- Base URL: `https://api.versionstory.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.versionstory.com/v1/api-keys`
- Auth: none declared

Get an API key by signing the user in through their browser; the one call that takes no key.
1. Make a PKCE pair: code_verifier, 43 to 128 random characters of A-Z, a-z, 0-9, -, ., _ or ~, and
code_challenge, its SHA-256 digest in base64url without padding. Make a random state.
2. Listen for one request on a free port of 127.0.0.1; redirect_uri is exactly
http://127.0.0.1:<port>/callback, with no query.
3. Open the authorize page in the user's browser: https://app.versionstory.com/developer/authorize.
Add the query client_name (what you are, such as "Claude Code on
<hostname>", which becomes the key's name), redirect_uri, code_challenge,
code_challenge_method=S256 and state. The user signs in or registers and allows the request; the
browser then calls redirect_uri with code and state, or with error=access_denied when they decline.
Check that state matches.
4. While the browser waits on redirect_uri, send code, code_verifier and redirect_uri to this call
(within five minutes), at https://api.versionstory.com. The answer carries api_key, once: store it where the user's
secrets live and never print it.
5. Answer the browser with a redirect to the authorize page's host at
/developer/authorize/complete?result=granted, or result=denied after error=access_denied, or
result=failed, which tells the user they are done.

## Request body

- ApiKeyExchangeRequest
  - `code` string, required: The code the authorize page sent to redirect_uri.
  - `code_verifier` string, required: The PKCE verifier whose S256 challenge the authorize page was given.
  - `redirect_uri` string, required: The redirect_uri the authorize page was given, unchanged.

## Response `201`

Successful Response

- ApiKeyExchangeResponse
  - `api_key` string, required
  - `name` string, required
  - `organization_id` string, required
  - `organization_name` string, required
  - `message` string, nullable

## Other responses

- `400`: The request is invalid: INVALID_REQUEST when a parameter or the body fails validation, otherwise the code of the operation's own refusal.

---

[API](https://skmtc.dev/versionstory/apis/version-story-public-api.md) - [All operations](https://skmtc.dev/versionstory/apis/version-story-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/versionstory/apis/version-story-public-api/revisions/994ce15faf32?raw)
