---
title: "Create Key"
method: POST
path: "/v1/keys"
tags: ["keys"]
---

# Create Key

`POST /v1/keys`

Create a new API key in the caller's organization.

Requires master key authentication.

If user_id is provided, the key will be associated with that user (creates user if it doesn't exist).
If user_id is not provided, the key is associated with the shared "default" user, which is created
on first use. Keys without an explicit owner therefore share one identity, and so share budget,
usage, and files.

``workspace_id`` names a workspace in the caller's organization, and omitting
it mints into that organization's default workspace. A key resolves that
organization's provider credentials and bills there, so minting into another
organization's workspace would spend its budget on its credentials.

## Request body

- CreateKeyRequest — Request model for creating a new API key.
  - `allowed_models` string[], nullable — Model allow-list: null = any model, [] = deny all, or canonical instance:model entries (with instance:* / instance:prefix* wildcards).
  - `capture_agent_telemetry` boolean, nullable — Per-key override of the deployment-wide capture_agent_telemetry setting: null (default) inherits it, true always stores this key's coding-agent telemetry, false always discards it. Covers both behavioral events (tool_result, tool_decision, user_prompt, api_error) from POST /v1/logs and outcome-metric data points (lines of code, commits, pull requests, active time) from POST /v1/metrics. Usage capture and billing are unaffected either way.
  - `exclude_from_budget` boolean — When true, requests on this key are logged with cost but never reserved, reconciled into the user's spend, or gated by budget.
  - `expires_at` string, date-time, nullable — Optional expiration timestamp
  - `key_name` string, nullable — Optional name for the key
  - `metadata` object — Optional metadata
  - `reject_user_mismatch` boolean, nullable — Per-key override of the deployment-wide reject_user_mismatch setting: null (default) inherits it, true always rejects a request naming a different 'user', false always accepts it. Spend binds to this key's own user either way.
  - `user_id` string, nullable — Optional user ID to associate with this key
  - `workspace_id` string, uuid, nullable — Workspace this key belongs to, which must be one in the caller's organization. Omitted means that organization's default workspace. A key belongs to exactly one workspace: requests on it are scoped and billed there, so the workspace is read off the key rather than off a request header.

## Response `200`

Successful Response

- CreateKeyResponse — Response model for creating a new API key.
  - `allowed_models` string[], nullable, required
  - `capture_agent_telemetry` boolean, nullable, required
  - `created_at` string, required
  - `exclude_from_budget` boolean, required
  - `expires_at` string, nullable, required
  - `id` string, required
  - `is_active` boolean, required
  - `key` string, required
  - `key_name` string, nullable, required
  - `key_prefix` string, nullable, required
  - `metadata` object, required
  - `reject_user_mismatch` boolean, nullable, required
  - `user_id` string, nullable, required

## Other responses

- `422` — Validation Error

## Changes

> 126 revisions in range; 84 could not be searched.

- **2026-07-23** `2a163c690f59` — 2 info
  - added the new optional request property `exclude_from_budget`
  - added the required property `exclude_from_budget` to the response with the `200` status
- **2026-04-17** `0f43605bdc13` — 1 info
  - the endpoint scheme security `ApiKeyAuth` was removed from the API

[Change history](https://skmtc.dev/mozilla-ai/apis/otari/changes/v1/keys/post.md)

---

[API](https://skmtc.dev/mozilla-ai/apis/otari.md) · [All operations](https://skmtc.dev/mozilla-ai/apis/otari/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/mozilla-ai/otari/revisions/7f178e92b56c/schema)
