# GET /v1/organizations/:orgId/api-keys (/docs/api/reference/organizations/api-keys/list)



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

To audit which keys a customer holds, list the keys on that customer's child organization. You call this with your parent (`org:admin`) key. The response is a **masked** view - it never contains the secret or its hash, only what you need to identify and manage each key. Use it to render a "keys for this customer" table, spot a key still in a rotation grace window, or confirm a revoke landed.

Results are **keyset (cursor) paginated**, newest first. Follow `nextCursor` until it comes back `null`.

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

<Parameters
  title="Query"
  rows="[
  { name: 'limit', type: 'integer', required: false, description: 'Page size, 1-100. Defaults to 25.' },
  { name: 'cursor', type: 'string', required: false, description: <>Opaque cursor from the previous response&apos;s <code>nextCursor</code>. Omit for the first page.</> },
]"
/>

## Example [#example]

```bash
curl "https://api.layers.com/v1/organizations/org_d4e5f6a7-8b9c-4d0e-9f2a-3b4c5d6e7f80/api-keys?limit=25" \
  -H "Authorization: Bearer $LAYERS_PARENT_KEY"
```

<Response status="200" description="OK">
  ```json
  {
    "items": [
      {
        "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": "2026-06-03T19:02:41.004Z",
        "rotatedAt": null,
        "revokedAt": null,
        "graceUntil": null,
        "supersededBy": null
      }
    ],
    "nextCursor": null
  }
  ```
</Response>

### Field notes [#field-notes]

* The **secret is never returned** by this endpoint - it only ever appears in the [mint](/docs/api/reference/organizations/api-keys/mint) and [rotate](/docs/api/reference/organizations/api-keys/rotate) responses. `prefix` is the safe-to-show lookup handle.
* `status` is `active` or `revoked`. A revoked, killed, or soft-deleted key all collapse to `revoked` - one wire status means one next action: re-mint.
* `graceUntil` is set on an **old** key during a rotation: its secret keeps working until this moment, then stops. `null` for any key not mid-rotation.
* `supersededBy` is the `key_…` id of the replacement when this key was rotated. Follow it to find the go-forward key.
* Keys are returned under `items`, the standard partner list envelope (`{ items, nextCursor }`) shared by every list endpoint.
* `nextCursor` is `null` on the last page. Treat the cursor as opaque - don't parse it.

## Errors [#errors]

| Status | Code          | When                                                                  |
| ------ | ------------- | --------------------------------------------------------------------- |
| 404    | `NOT_FOUND`   | `:orgId` is not a direct child of your org (anti-enumeration).        |
| 422    | `VALIDATION`  | Malformed `:orgId`, or an out-of-range `limit`.                       |
| 503    | `KILL_SWITCH` | Your key or org is suspended; or the child org is suspended/archived. |

## See also [#see-also]

* [Mint a child key](/docs/api/reference/organizations/api-keys/mint) - create a key, get the secret once.
* [Rotate](/docs/api/reference/organizations/api-keys/rotate) - read `graceUntil` / `supersededBy` here after rotating.
* [Delete](/docs/api/reference/organizations/api-keys/delete) - immediate revoke.
* [Pagination](/docs/api/getting-started/common-patterns) - the cursor contract.
