keys

Create an API key

The secret is returned exactly once. The key is always minted into the calling key’s workspace. Pass scopes to narrow what the key may do; omit it for the default set (runs:write, runs:read, vault:read, vault:write, verify). Add mcp explicitly for a key a headless agent will present to the MCP server; it is never in the default set and admin does not imply it. Add admin:read — alone, on a key named operator-diagnostics — for the operator diagnostic read (GET /v1/admin/runs*); it grants no write and no health, billing or backfill endpoint, and admin implies it. A key form should show the scopes before minting: production minted write access to runs and the vault from a form that named none of it (E2E3-14).

post/v1/keys

Request

  • Base URL: https://api.hyperresearch.ai
  • URL: https://api.hyperresearch.ai/v1/keys
  • Auth: one of:
    • HTTP bearer
    • API key in cookie hr_session

Request body

namestring
prefix'hr_live_' | 'hr_test_'
scopesstring[]

What this key may do. Omit it for the default set — runs:write, runs:read, vault:read, vault:write, verify — which is what every key minted before this field existed carries. Valid values: runs:write, runs:read, vault:read, vault:write, verify, mcp, admin, admin:read. An unknown scope is a 400 on scopes, never a silently dropped field, and an empty array is refused: a key that can do nothing is a mistake. admin is owner-equivalent — it implies every other scope except mcp — so grant it deliberately. mcp lets this key open a session with the MCP server at https://mcp.hyperresearch.ai/mcp (Authorization: Bearer <key>), for a headless agent that has no browser for the OAuth flow. It is a front-door marker only: every tool still needs its own data scope, so pair it with vault:read / runs:read as needed. It is never granted by default and never implied by admin. admin:read is the operator diagnostic read (GET /v1/admin/runs*, ops/diagnosing-a-run.md): the one scope here that is not bounded by the key’s own workspace, and the one that grants no write anywhere and no health, billing or backfill endpoint. Grant it alone, on a key named operator-diagnostics. It is never in the default set; admin implies it, so granting both is redundant rather than wrong.

expires_atstring date-time
ip_allowliststring[]

Example request

{
  "scopes": [
    "runs:read",
    "vault:read"
  ]
}

Response

Created

idstring required
namestring nullable required
prefix'hr_live_' | 'hr_test_' | 'hr_chat_' required
maskedstring required
scopesstring[] required
last_used_atstring nullable required
expires_atstring nullable required
revoked_atstring nullable required
created_atstring required
ip_allowliststring[] required
rotate_bystring nullable required
rotation_dueboolean required
secretstring required

Example response

{
  "id": "key_01J9ZQ7V6H0000000000000000",
  "masked": "hr_live_7Qa1bC3dE5f9…",
  "secret": "hr_live_7Qa1bC3dE5f9…"
}

Changes

No recorded changes to this operation across all 1 revision of this API.