Skip to main content
Identities let you enforce a single rate limit across all of a user’s API keys. Without this, a user with 5 keys at 100 req/s each could make 500 req/s total — probably not what you want.

The problem

Without shared limits, rate limits apply per-key:
User has 3 API keys, each with 100 req/s limit
→ User can actually make 300 req/s (100 × 3 keys)

The solution

Create an identity for the user, attach a rate limit to it, then link all their keys to that identity:
Identity: user_123
  └── Rate limit: 100 req/s (shared pool)
      ├── Key A (production)
      ├── Key B (staging)
      └── Key C (mobile app)

→ User can only make 100 req/s total across ALL keys

Step 1: Create an identity with rate limits

curl -X POST https://api.unkey.com/v2/identities.createIdentity \
  -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "user_123",
    "ratelimits": [
      {
        "name": "requests",
        "limit": 100,
        "duration": 1000
      }
    ]
  }'

Step 2: Create keys linked to the identity

curl -X POST https://api.unkey.com/v2/keys.createKey \
  -H "Authorization: Bearer $UNKEY_ROOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "apiId": "api_...",
    "externalId": "user_123",
    "name": "Production Key"
  }'

Step 3: Verify — limits are shared automatically

When you verify any key linked to the identity, the shared rate limit is enforced:
const { meta, data } = await verifyKey({ key: "sk_prod_..." });

// If the identity is rate limited, data.valid will be false
if (!data.valid && data.code === "RATE_LIMITED") {
  // User exceeded 100 req/s across ALL their keys
}

Multiple rate limits

You can set multiple limits on an identity — useful for different resource types:
try {
  const { meta, data } = await unkey.identities.create({
    externalId: "user_123",
    ratelimits: [
      {
        name: "requests",
        limit: 500,
        duration: 3600000,  // 500 requests per hour
      },
      {
        name: "tokens",
        limit: 20000,
        duration: 86400000,  // 20k tokens per day
      },
    ],
  });
} catch (err) {
  console.error(err);
  throw err;
}
Then specify which limit to check during verification:
// Check the "tokens" limit and consume 150 tokens
const { meta, data } = await verifyKey({
  key: "sk_...",
  ratelimits: [
    { name: "tokens", cost: 150 },
  ],
});
If any specified limit is exceeded, verification fails.

Next steps

Last modified on February 16, 2026