# POST /v1/organizations/:orgId/api-keys (/docs/api/reference/organizations/api-keys/mint)



<Endpoint method="POST" path="/v1/organizations/{orgId}/api-keys" auth="Bearer" scope="org:admin" phase="1" />

To give one of your customers their own credential, mint a key directly against that customer's child organization. You call this with your parent (`org:admin`) key; the new key belongs to the child named in the path and carries only the access you choose. The plaintext secret comes back **once**, in this response, and can never be retrieved again.

A child key is a least-privilege credential. Mint a key that can read content for one customer, another that can run ads for another - each scoped to exactly one child org and exactly the scopes that customer's integration needs.

## What the child key can be granted [#what-the-child-key-can-be-granted]

`scopes` must be a **subset of your own** key's scopes - you cannot hand a child more access than you hold. And `org:admin` is **never delegable**: a child key can never run the control plane (mint its own children, move projects, drain wallets). Request it and the call is rejected with `403 FORBIDDEN_SCOPE`.

`scopes` is **required** — pass at least one. A key with no scopes is denied on every route, so a scope-less mint is rejected with `422 VALIDATION`. See [API keys → child keys](/docs/api/concepts/api-keys#child-keys-for-sub-organizations) for the subsetting rules.

<Parameters
  title="Path"
  rows="[
  { name: 'orgId', type: 'string (org_…)', required: true, description: 'The child organization to mint the key for. Must be a direct child of your org - otherwise 404.' },
]"
/>

<Parameters
  title="Body"
  rows="[
  { name: 'name', type: 'string', required: true, description: 'Human-readable label for the key, 1-120 chars. Shown in list responses and audit logs - name it after the integration, not the developer.' },
  { name: 'scopes', type: 'string[]', required: true, description: <>Scopes to grant the child key. At least one is required (1-64 entries). Must be a subset of your own scopes; <code>org:admin</code> is rejected with <code>403 FORBIDDEN_SCOPE</code>.</> },
  { name: 'env', type: '&#x22;live&#x22; | &#x22;test&#x22;', required: false, description: <>Environment for the key. Defaults to <code>live</code>. A <code>test</code> key lands on the <code>sandbox</code> rate-limit tier and exercises the sandbox behavior contract.</> },
]"
/>

<Parameters
  title="Headers"
  rows="[
  { name: 'Idempotency-Key', type: 'string (UUID)', required: false, description: 'Strongly recommended. A replay returns the SAME minted key + secret - without it, a network retry silently mints a second key and leaves you holding the wrong secret.' },
]"
/>

## Example [#example]

```bash
curl -X POST https://api.layers.com/v1/organizations/org_d4e5f6a7-8b9c-4d0e-9f2a-3b4c5d6e7f80/api-keys \
  -H "Authorization: Bearer $LAYERS_PARENT_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "acme-content-sync",
    "scopes": ["content:read", "content:write"],
    "env": "live"
  }'
```

<Response status="201" description="Created - key minted, secret returned once">
  ```json
  {
    "apiKey": {
      "id": "key_c2037bb9-354d-4662-96b7-97a28ad6b6e1",
      "organizationId": "org_d4e5f6a7-8b9c-4d0e-9f2a-3b4c5d6e7f80",
      "name": "acme-content-sync",
      "prefix": "lp_live_ABCDEFGHJKMNPQRS",
      "env": "live",
      "scopes": ["content:read", "content:write"],
      "rateLimitTier": "standard",
      "status": "active",
      "createdAt": "2026-06-03T18:14:02.187Z",
      "lastUsedAt": null,
      "rotatedAt": null,
      "revokedAt": null,
      "graceUntil": null,
      "supersededBy": null
    },
    "secret": "lp_live_...",
    "warning": "Store this secret now. It cannot be retrieved again. Rotate the key if it's lost."
  }
  ```
</Response>

### Field notes [#field-notes]

* `secret` is the full credential the child integration sends as `Authorization: Bearer <secret>`. It appears **only here** - copy it into your secrets manager before you do anything else.
* `prefix` is the public, non-secret lookup handle. It's safe to log and store; it is not the secret.
* `id` (`key_…`) is the public key identifier - use it to [list](/docs/api/reference/organizations/api-keys/list), [rotate](/docs/api/reference/organizations/api-keys/rotate), or [delete](/docs/api/reference/organizations/api-keys/delete) the key. It also appears in audit-log attribution.
* `scopes` echoes exactly what was granted - the subset that survived the check.

## Errors [#errors]

| Status | Code                   | When                                                                                                                                                                        |
| ------ | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 403    | `FORBIDDEN_SCOPE`      | A requested scope isn't a subset of your own, or `org:admin` was requested (never delegable). `details.offendingScopes` names the rejected scope(s).                        |
| 404    | `NOT_FOUND`            | `:orgId` is not a direct child of your org (anti-enumeration - a stranger's org looks identical to a missing one).                                                          |
| 422    | `VALIDATION`           | Malformed `:orgId`, or a body that fails validation (missing `name`, `name` too long, &#x2A;*missing or empty `scopes`**, an unknown scope string, or more than 64 scopes). |
| 409    | `IDEMPOTENCY_CONFLICT` | `Idempotency-Key` reused with a different body.                                                                                                                             |
| 503    | `KILL_SWITCH`          | Your key or org is suspended; or the child org is suspended/archived.                                                                                                       |

## See also [#see-also]

* [List child keys](/docs/api/reference/organizations/api-keys/list) - masked view of every key on a child.
* [Rotate](/docs/api/reference/organizations/api-keys/rotate) - zero-downtime secret rollover with a 24h grace.
* [Delete](/docs/api/reference/organizations/api-keys/delete) - immediate revoke, no grace.
* [API keys → child keys](/docs/api/concepts/api-keys#child-keys-for-sub-organizations) - scope subsetting and the `org:admin` rule.
* [Organizations](/docs/api/concepts/organizations) - how sub-organizations model your customers.
