본문으로 건너뛰기

API Keys & Provisioning

Issue and manage plm_ API keys, and provision child keys with a management key for automation.

The /v1/keys and /v1/management-keys endpoints are for dashboard management and authenticate with your logged-in session's JWT access token (Authorization: Bearer $PLEUM_SESSION_TOKEN). They cannot be called with a plm_ key or an SDK-compatible token. The plm_ keys you create here are what you then use for OpenAI / Anthropic SDK calls.

Use a JWT to manage keys in the dashboard and a personal plm_ key for model inference. A plmk_ management key is only for issuing automation child keys through /v1/provisioning/keys. Both secret key types are shown once at creation.

Personal keys#

GET/v1/keys
GET/v1/keys/usage
POST/v1/keys
PATCH/v1/keys/{id}
DELETE/v1/keys/{id}

Create a new key with POST /v1/keys. All body fields are optional; omitted fields fall back to their defaults.

ParameterTypeRequiredDescription
namestring | nullOptionalKey name. Defaults to "Default".
allowed_modelsstring[] | nullOptionalAllowlist of model IDs this key may call. Empty or null allows all models.
monthly_budget_krwinteger | nullOptionalMonthly limit in KRW. null means unlimited.
weekly_budget_krwinteger | nullOptionalWeekly limit in KRW. Rolling 7 days in UTC. null means unlimited.
daily_budget_krwinteger | nullOptionalDaily limit in KRW. Rolling 24 hours. null means unlimited.
monthly_token_limitinteger | nullOptionalMonthly cap on combined input+output tokens. null means unlimited. Exceeding returns 402.
expires_atdatetime | nullOptionalKey expiry time (ISO 8601). null means no expiry.
pii_masking_enabledbooleanOptionalWhether outbound PII masking is applied. Defaults to true.
response_cache_modestringOptionaloff | exact | semantic. Defaults to off. See "Key scopes" below.
scopesstring[] | nullOptionalPermission scopes. Any combination of "chat", "usage:read", "images", "video", "audio", and "3d"; other values return 422.
ip_allowliststring[] | nullOptionalAllowed IP/CIDR list (e.g. 203.0.113.0/24). null means no restriction. Invalid entries return 422.
create key
curl https://apirouter.pleum.ai/v1/keys \
  -H "Authorization: Bearer $PLEUM_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "production",
    "allowed_models": ["gpt-5.5", "claude-sonnet-4-6"],
    "monthly_budget_krw": 50000,
    "weekly_budget_krw": 20000,
    "daily_budget_krw": null,
    "expires_at": null,
    "pii_masking_enabled": true,
    "response_cache_mode": "off",
    "scopes": ["chat"],
    "ip_allowlist": ["203.0.113.0/24"]
  }'

The response includes the key metadata plus key (the full secret). The full key is shown only once at creation — afterward only the key_prefix (e.g. plm_a1b2) is retrievable. Store it somewhere safe right away.

200 OK
{
  "id": "3f9b2c1e-7a4d-4e8b-9c6a-1d2e3f4a5b6c",
  "name": "production",
  "key_prefix": "plm_a1b2",
  "key": "plm_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
  "allowed_models": ["gpt-5.5", "claude-sonnet-4-6"],
  "monthly_budget_krw": 50000,
  "weekly_budget_krw": 20000,
  "daily_budget_krw": null,
  "monthly_token_limit": null,
  "is_active": true,
  "pii_masking_enabled": true,
  "response_cache_mode": "off",
  "scopes": ["chat"],
  "ip_allowlist": ["203.0.113.0/24"],
  "created_at": "2026-06-27T09:00:00Z",
  "expires_at": null
}
Regulated-industry accounts (finance, healthcare, government) cannot create a key with pii_masking_enabled=false, nor turn masking off — doing so returns a 403.

Key scopes#

When scopes is set, each API requires its matching permission: "chat" for model calls, "images" for image generation/editing, "video" for video generation, "audio" for speech/audio APIs, and "3d" for 3D generation. "usage:read" allows the read-only usage report ( GET /v1/usage/report). Reading a generation job also requires that job's modality scope. null (the default) keeps the legacy behavior with no per-route scope restriction, except that GET /v1/usage/report always requires the usage:read scope.

ParameterTypeRequiredDescription
scopesstring[] | nullOptionalAny combination of "chat", "usage:read", "images", "video", "audio", and "3d". null = legacy (no per-route restriction, except the usage report).
ip_allowliststring[] | nullOptionalRestricts key usage to these IP/CIDR ranges. Enforced at every key auth point; null means no restriction.
response_cache_modestringOptionaloff (default) | exact (exact request match) | semantic (exact match + embedding similarity). On a cache hit the response is served without a provider call, nothing is billed, and the response carries "cached": true.

Management & provisioning keys#

GET/v1/management-keys
POST/v1/management-keys
DELETE/v1/management-keys/{id}

Issue a plmk_ management key with POST /v1/management-keys (body {name}). A management key is used to provision child keys, and the full key is shown only once at creation. It supports GET · POST (201) · DELETE.

GET/v1/provisioning/keys
POST/v1/provisioning/keys
DELETE/v1/provisioning/keys/{id}

The provisioning endpoint (/v1/provisioning/keys) authenticates with the plmk_ management key, not a JWT (Authorization: Bearer plmk_xxxxxxxxxxxxxxxx). It is meant for CI / automation that needs to mint keys without a dashboard session. It supports GET (list the owner's keys) · POST (201, create a child key) · DELETE.

provision child key
export PLEUM_MANAGEMENT_KEY=plmk_xxxxxxxxxxxxxxxx

curl https://apirouter.pleum.ai/v1/provisioning/keys \
  -H "Authorization: Bearer $PLEUM_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ci-runner",
    "monthly_budget_krw": 20000
  }'

A child key created through provisioning accepts only name, monthly_budget_krw, and monthly_token_limit — you cannot set allowed_models, pii_masking_enabled, or expires_at.