---
title: "Generate Agent Api Key"
method: POST
path: "/api/agents/{agent_id}/api-key"
tags: ["agents"]
---

# Generate Agent Api Key

`POST /api/agents/{agent_id}/api-key`

Generate or rotate the SDK API key for an agent.

If an active (non-revoked) key already exists for the agent, this
endpoint revokes it and inserts a new active row in a single
transaction. The new ``full_key`` is returned exactly once in the
response; the plaintext secret is never persisted server-side, only
its bcrypt hash.

Args:
    agent_id: Path parameter; the target agent's primary key.
    current_user: Resolved from the ``Authorization: Bearer <JWT>``
        header by ``get_current_user``.
    db: SQLAlchemy session injected by FastAPI.

Returns:
    :class:`APIKeyGenerateResponse` containing ``full_key`` (one-shot
    plaintext), ``key_prefix``, and ``created_at``.

Raises:
    HTTPException 401: missing or invalid JWT.
    HTTPException 404: agent does not exist or does not belong to the
        caller (deliberate to avoid leaking agent existence).
    HTTPException 500: any unexpected error; transaction rolled back.
        The most plausible internal failure is a partial-unique index
        violation from a concurrent POST race, which the DB enforces.

Notes:
    - Transactional shape mirrors ``auth.setup_admin`` and
      ``custom_api.create_custom_api`` -- we collect all writes in the
      session and commit once. There is no ``SELECT ... FOR UPDATE``;
      concurrent rotations are caught by the
      ``uq_agent_api_keys_agent_active`` partial unique index and
      surfaced as a 500. Two clients racing to rotate the same key is
      a corner case; a 500 is acceptable.
    - Logs include the ``key_prefix`` only -- never the ``full_key``,
      the secret half, or the bcrypt hash.

## Path parameters

- `agent_id` integer, required

## Response `200`

Successful Response

- APIKeyGenerateResponse — Response model for ``POST /api/agents/{agent_id}/api-key``. The ``full_key`` is plaintext and returned exactly once per rotation. Clients (the web UI) must show it to the agent owner immediately and warn that it will not be retrievable later. The server only persists ``bcrypt(full_key)`` in ``agent_api_keys.key_hash``; the plaintext leaves this response and is never written to disk server-side.
  - `full_key` string, required — Plaintext API key in the format xag_<6 chars>_<32 chars>. Returned exactly once; cannot be retrieved later.
  - `key_prefix` string, required — Public-safe 6-char lookup handle. Same value embedded in the full_key middle segment; returned separately so the UI does not have to re-parse the full key.
  - `created_at` string, date-time, required — UTC timestamp when the new key was persisted.

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/xorbitsai/apis/xagent.md) · [All operations](https://skmtc.net/xorbitsai/apis/xagent/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/xorbitsai/xagent/versions/33e4ba4936ad/schema)
