> ## Documentation Index
> Fetch the complete documentation index at: https://unkey.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API key

> Reference for Principal fields produced by Sentinel API key authentication including key ID, owner, permissions, and custom metadata.

<Info>
  Unkey Deploy is in public beta. To try it, open the product switcher in the
  top-left of the dashboard and select **Deploy**. During beta, deployed
  resources are free. We're eager for feedback, so let us know what you think
  on [Discord](https://unkey.com/discord), [X](https://x.com/unkeydev), or
  email [support@unkey.com](mailto:support@unkey.com).
</Info>

When the [Principal's](/platform/sentinel/principal/overview) `type` is `"API_KEY"`, the `source.key` object contains the full details of the verified API key. This page documents every field in the API key source.

## Fields

<ResponseField name="source.key.keyId" type="string" required>
  The ID of the API key that authenticated the request. When the key is linked to an identity, the top-level `subject` is the identity's external ID, so use this field when you need to identify the specific key that was used (for example, for key-level analytics or revocation).
</ResponseField>

<ResponseField name="source.key.keySpaceId" type="string" required>
  The ID of the keyspace the key belongs to. Useful when your Sentinel is configured with multiple keyspaces and your application needs to distinguish which keyspace matched.
</ResponseField>

<ResponseField name="source.key.name" type="string">
  The human-readable name of the key, if one was set when the key was created. Absent when the key has no name. Useful for displaying which key was used in dashboards or audit logs (for example, "ACME Production Key").
</ResponseField>

<ResponseField name="source.key.expiresAt" type="integer">
  Unix timestamp in **milliseconds** when the key expires. Absent when the key has no expiry. The Sentinel already rejects expired keys, so if this field is present the key is still valid. Your application can use it to warn users about upcoming expiration.
</ResponseField>

<ResponseField name="source.key.meta" type="object" required>
  Custom key-value metadata attached to the key. This is the same metadata you set through the Unkey API when creating or updating the key. Use it to pass per-key attributes to your application, for example an environment label or a customer tier. Empty `{}` when no metadata is set.
</ResponseField>

<ResponseField name="source.key.roles" type="string[]">
  The roles attached to the key, as flat string identifiers (for example, `["admin", "billing"]`). Omitted entirely when no roles are attached. These are the raw role names from Unkey, available for your application's own authorization logic.
</ResponseField>

<ResponseField name="source.key.permissions" type="string[]">
  The permissions attached to the key, as flat string identifiers (for example, `["api.read", "api.write"]`). Omitted entirely when no permissions are attached.

  These are the raw permissions from Unkey. If the Sentinel enforced a [permission query](/platform/sentinel/policies/api-key) and the key lacked the required permissions, the request was already rejected before reaching your app. The permissions here let your application make additional fine-grained authorization decisions beyond what the Sentinel enforces.
</ResponseField>

## Examples

<CodeGroup>
  ```json Without identity theme={"theme":"kanagawa-wave"}
  {
    "version": "v1",
    "subject": "key_3xMpL9kF2nR",
    "type": "API_KEY",
    "source": {
      "key": {
        "keyId": "key_3xMpL9kF2nR",
        "keySpaceId": "ks_abc123",
        "name": "ACME Production Key",
        "expiresAt": 1717200000000,
        "meta": {
          "environment": "production"
        },
        "roles": ["admin", "billing"],
        "permissions": ["api.read", "api.write", "billing.manage"]
      }
    }
  }
  ```

  ```json With linked identity theme={"theme":"kanagawa-wave"}
  {
    "version": "v1",
    "subject": "user_42",
    "type": "API_KEY",
    "identity": {
      "externalId": "user_42",
      "meta": {
        "plan": "pro",
        "org": "acme"
      }
    },
    "source": {
      "key": {
        "keyId": "key_3xMpL9kF2nR",
        "keySpaceId": "ks_abc123",
        "name": "ACME Production Key",
        "meta": {},
        "roles": ["admin"],
        "permissions": ["api.read", "api.write"]
      }
    }
  }
  ```

  ```json Minimal theme={"theme":"kanagawa-wave"}
  {
    "version": "v1",
    "subject": "key_3xMpL9kF2nR",
    "type": "API_KEY",
    "source": {
      "key": {
        "keyId": "key_3xMpL9kF2nR",
        "keySpaceId": "ks_abc123",
        "meta": {}
      }
    }
  }
  ```
</CodeGroup>
