---
title: "Create Connector Key"
method: POST
path: "/api/v1/admin/keys/connector"
tags: ["admin"]
---

# Create Connector Key

`POST /api/v1/admin/keys/connector`

## Request

- Base URL: `https://core.mnemoverse.com`
- URL: `https://core.mnemoverse.com/api/v1/admin/keys/connector`
- Auth: API key in header `X-Admin-Key`

Get-or-create the per-user API key the remote MCP server (RS) uses to call
core on behalf of a connector user. TWO proofs (like ``/keys/self-serve``): the
``X-Admin-Key`` (caller = the trusted RS) AND the user's OIDC access token
forwarded as ``X-Connector-Token`` (verified against the AS JWKS). The org is
DERIVED from the verified ``sub`` (``user_<sub>``), never from the body — so this
path may target the reserved ``user_`` namespace WITHOUT weakening the
``POST /admin/keys`` guard.

Revokes any prior active connector key for this (user, client_label) and mints a
fresh one (the raw key is only knowable at creation; the RS caches it). Invariant:
at most one ACTIVE connector key per (user, client_label) — different clients
(claude, chatgpt, ...) hold their own keys simultaneously; the NULL group (older
RS builds) is matched via IS NOT DISTINCT FROM. All keys are tagged
``name="__connector__"`` so they never collide with the user's own portal keys.

Tier and limits come from the ORG SUBSCRIPTION, not the body: enforcement
(``DailyQuotaMiddleware`` in ``usage.py``) reads limits from the KEY row, so
connector traffic must carry the org plan rather than hardcoded free defaults.
Keys rotate hourly, so later plan changes self-heal within an hour. The body's
tier/limit fields are IGNORED (wire compat with older RS builds only).

## Request body

- ConnectorKeyRequest: Body for ``POST /admin/keys/connector``. NOTE: ``tier`` / ``rate_limit_per_min`` / ``atom_limit`` / ``daily_query_limit`` are now IGNORED — kept only for wire compatibility with older RS builds. The minted key inherits the org subscription instead (see ``create_connector_key``). Unknown extra body fields are ignored too (Pydantic default), so newer RS builds can add fields without 422-ing older cores.
  - `tier` string: IGNORED — key inherits the org subscription.
  - `rate_limit_per_min` integer: IGNORED — inherited.
  - `atom_limit` integer: IGNORED — inherited.
  - `daily_query_limit` integer: IGNORED — inherited.
  - `client_label` string, nullable: RS-computed client classification (e.g. 'claude', 'chatgpt'). One logical connection per (user, client_label); NULL = legacy/unknown client.

## Response `200`

Successful Response

- CreateKeyResponse
  - `id` string, required
  - `key` string, required: Full API key — returned only once.
  - `key_prefix` string, required
  - `organization_id` string, required
  - `tier` string, required

## Other responses

- `400`: Validation error
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not found
- `422`: Validation Error
- `429`: Rate limited
- `500`: Internal server error
- `503`: Service unavailable

---

[API](https://skmtc.dev/mnemoverse/apis/mnemoverse-core.md) · [All operations](https://skmtc.dev/mnemoverse/apis/mnemoverse-core/llms.txt) · [OpenAPI document](https://skmtc.dev/mnemoverse/apis/mnemoverse-core/revisions/1f5e0048f017?raw)
