diff --git a/apps/docs/concepts/identities/credits.mdx b/apps/docs/concepts/identities/credits.mdx
new file mode 100644
index 0000000000..36ada136ed
--- /dev/null
+++ b/apps/docs/concepts/identities/credits.mdx
@@ -0,0 +1,99 @@
+---
+title: Credits
+description: "Identities can be used to share credits across multiple keys"
+---
+
+
+ Identities are in public beta, please report any issues you encounter:
+ [support](mailto:support@unkey.dev).
+
+
+## Sharing credits
+
+Identities let you share a credit pool across multiple keys. For example, if you want to give a user 1000 credits per month:
+
+Without identities: Setting 1000 credits per key means a user with 3 keys gets 3000 total credits (1000 × 3).
+
+With identities: Create an identity with 1000 credits and associate all the user's keys with it. Now all keys share the same pool of 1000 credits.
+
+## How it works
+
+When you configure credits on an identity:
+
+1. **Shared counter**: All keys associated with the identity draw from the same credit counter
+2. **Automatic refills**: You can configure automatic refills (daily or monthly) to reset credits periodically
+
+When a key with identity credits is verified, the credit cost is deducted from the shared identity counter, ensuring consistent usage tracking across all of the user's keys.
+
+## Example use case
+
+Let's say you're building a SaaS product with different subscription tiers:
+
+- **Free tier**: 100 credits per day
+- **Pro tier**: 10,000 credits per month
+- **Enterprise**: Unlimited (no credits configured)
+
+When a user signs up for the Pro tier:
+
+```typescript
+// Create the identity with credits
+const identity = await unkey.identities.createIdentity({
+ externalId: user.id,
+ credits: {
+ remaining: 10000,
+ refill: {
+ interval: "monthly",
+ amount: 10000,
+ refillDay: 1, // Refill on the 1st of each month
+ },
+ },
+});
+
+// Create keys for the user
+const key1 = await unkey.keys.create({
+ apiId: "api_123",
+ identityId: identity.id,
+});
+
+const key2 = await unkey.keys.create({
+ apiId: "api_123",
+ identityId: identity.id,
+});
+```
+
+Now both `key1` and `key2` share the same 10,000 credits. If the user consumes 3,000 credits with `key1`, they'll have 7,000 credits remaining for both keys combined.
+
+### Updating tiers
+
+When a user upgrades or downgrades their subscription, you can update their credits accordingly:
+
+```typescript
+// User upgrades from Pro to Enterprise (unlimited)
+await unkey.identities.updateIdentity({
+ identityId: identity.id,
+ credits: null, // Remove credit limits for unlimited usage
+});
+
+// User downgrades from Pro to Free tier
+await unkey.identities.updateIdentity({
+ identityId: identity.id,
+ credits: {
+ remaining: 100,
+ refill: {
+ interval: "daily",
+ amount: 100,
+ },
+ },
+});
+```
+
+When you update the credits configuration, all keys associated with the identity will immediately use the new credit limits. This makes it easy to handle subscription changes without having to update each individual key.
+
+
+ API reference for creating identities: [/api-reference/v2/identities/create-identity](https://www.unkey.com/docs/api-reference/v2/identities/create-identity)
+
+API reference for creating keys: [/api-reference/v2/keys/create-api-key](https://www.unkey.com/docs/api-reference/v2/keys/create-api-key)
+
+API reference for verifying keys: [/api-reference/v2/keys/verify-api-key](https://www.unkey.com/docs/api-reference/v2/keys/verify-api-key)
+
+
diff --git a/apps/docs/concepts/identities/overview.mdx b/apps/docs/concepts/identities/overview.mdx
index 9c7281b976..d2d95fb053 100644
--- a/apps/docs/concepts/identities/overview.mdx
+++ b/apps/docs/concepts/identities/overview.mdx
@@ -3,15 +3,14 @@ title: Overview
description: "Identities are a representations of a user, an org or a machine in your application."
---
-
- Identities are in in public beta, please report any issues you encounter: [support](mailto:support@unkey.dev).
+ Identities are in public beta, please report any issues you encounter:
+ [support](mailto:support@unkey.dev).
-Identities are used to map your users, organizations, or even machine-users in Unkey and allow you to share metadata and configuration across multiple keys.
+Identities are used to map your users, organizations, or even machine-users in Unkey and allow you to share metadata and configuration across multiple keys.
An identity is directly linked via a unique identifier from your system and you can associate as many keys as you want with an identity.
-
## Use cases
### Multiple keys for the same user
@@ -20,36 +19,72 @@ It is very common to issue multiple keys for the same user, but managing metadat
Instead of updating each key, you can update the identity and all keys associated with it will automatically get the updated metadata and configuration.
-
### Sharing ratelimits across multiple keys
If you have multiple keys for the same user, you can set ratelimits for the identity and share it across all keys. This way, you can ensure that the user does not exceed the ratelimits across all of their keys.
[Read more](/concepts/identities/ratelimits) about how to share ratelimits across multiple keys.
+### Sharing credits across multiple keys
+
+When you configure credits on an identity, all keys associated with that identity will share the same credit counter. This is useful when:
+
+- A user has multiple devices or API keys and you want to track their total usage across all keys
+- You want to enforce a single usage limit per user, regardless of how many keys they have
+- You're building a subscription-based product where credit limits are tied to the user, not individual keys
+
+When a key with identity credits makes a request, the credits are deducted from the shared identity counter. This ensures that the total usage across all of a user's keys doesn't exceed their allocated credits.
+
+**Example:** If an identity has 1000 credits and a user creates 3 keys linked to that identity, all 3 keys will share the same 1000 credits. If key A uses 400 credits, keys B and C together can only use the remaining 600 credits.
+
+[Read more](/concepts/identities/credits) about how to share credits across multiple keys.
+
### Aggregated analytics
If you are building a multi-tenant product, you can associate all keys of an organization with the organization's identity. This way, you can aggregate analytics across all keys of the organization and provide insights to the organization admin or drive your billing.
-
## Data model
-
- The unique identifier of the identity in Unkey. You may use this to reference the identity in other API calls.
+
+ The unique identifier of the identity in Unkey. You may use this to reference
+ the identity in other API calls.
The id of the identity in your system. This is used to link the identity in Unkey to your system.
For example your user id, or organization id if you are linking an organization.
+If you are using a 3rd party auth provider like Clerk, WorkOS, or Auth0, they will provide you a unique id for users and organizations. This is what you should use as the externalId.
- If you are using a 3rd party auth provider like Clerk, WorkOS, or Auth0, they will provide you a unique id for users and organizations. This is what you should use as the externalId.
+We want to build deeper integrations with them, so if you are using one of these, please let us know so we can prioritize it.
- We want to build deeper integrations with them, so if you are using one of these, please let us know so we can prioritize it.
-
- A JSON object that can store any additional information about the identity.
- We do not make assumptions about this data, it's entirely up to you to decide what to store here.
+ A JSON object that can store any additional information about the identity. We
+ do not make assumptions about this data, it's entirely up to you to decide
+ what to store here.
+
+
+
+ An array of ratelimit configurations that apply to all keys associated with this identity.
+ When configured, all keys linked to the identity will share these ratelimits, ensuring
+ that the total usage across all keys doesn't exceed the specified limits.
+
+ [Read more](/concepts/identities/ratelimits) about sharing ratelimits.
+
+
+
+ Credit configuration for the identity. When configured, all keys associated with this
+ identity will share the same credit counter. This is useful for enforcing usage limits
+ per user regardless of how many keys they have.
+
+ The credits object contains:
+ - `remaining` (number): The current number of credits available
+ - `refill` (object, optional): Automatic refill configuration
+ - `interval` ("daily" | "monthly"): How often credits refill
+ - `amount` (number): How many credits to add on refill
+ - `refillDay` (number, optional): Day of month for monthly refills (1-31)
+
+ [Read more](/concepts/identities/credits) about sharing credits.
diff --git a/apps/docs/concepts/identities/ratelimits.mdx b/apps/docs/concepts/identities/ratelimits.mdx
index 152dd2fbcb..78fce295cb 100644
--- a/apps/docs/concepts/identities/ratelimits.mdx
+++ b/apps/docs/concepts/identities/ratelimits.mdx
@@ -4,7 +4,7 @@ description: "Identities can be used to share ratelimits across multiple keys"
---
- Identities are in in public beta, please report any issues you encounter: [support](mailto:support@unkey.dev).
+ Identities are in public beta, please report any issues you encounter: [support](mailto:support@unkey.dev).
## Sharing ratelimits
diff --git a/apps/docs/docs.json b/apps/docs/docs.json
index ed595cb096..1d4117d3a4 100644
--- a/apps/docs/docs.json
+++ b/apps/docs/docs.json
@@ -79,9 +79,7 @@
},
{
"group": "Identities",
- "pages": [
- "quickstart/identities/shared-ratelimits"
- ]
+ "pages": ["quickstart/identities/shared-ratelimits"]
}
]
},
@@ -117,7 +115,8 @@
"icon": "fingerprint",
"pages": [
"concepts/identities/overview",
- "concepts/identities/ratelimits"
+ "concepts/identities/ratelimits",
+ "concepts/identities/credits"
]
}
]
@@ -135,9 +134,7 @@
"pages": [
{
"group": "Ratelimiting",
- "pages": [
- "apis/features/ratelimiting/overview"
- ]
+ "pages": ["apis/features/ratelimiting/overview"]
},
"apis/features/temp-keys",
"apis/features/remaining",
@@ -172,10 +169,7 @@
{
"group": "Audit logs",
"icon": "scroll",
- "pages": [
- "audit-log/introduction",
- "audit-log/types"
- ]
+ "pages": ["audit-log/introduction", "audit-log/types"]
},
{
"group": "Analytics",
@@ -197,10 +191,7 @@
{
"group": "Migrating API Keys",
"icon": "plane",
- "pages": [
- "migrations/introduction",
- "migrations/keys"
- ]
+ "pages": ["migrations/introduction", "migrations/keys"]
}
]
},
@@ -282,9 +273,7 @@
},
{
"group": "Too Many Requests",
- "pages": [
- "errors/user/too_many_requests/query_quota_exceeded"
- ]
+ "pages": ["errors/user/too_many_requests/query_quota_exceeded"]
},
{
"group": "Unprocessable Entity",
@@ -390,15 +379,11 @@
},
{
"group": "Go",
- "pages": [
- "libraries/go/api"
- ]
+ "pages": ["libraries/go/api"]
},
{
"group": "Python",
- "pages": [
- "libraries/py/api"
- ]
+ "pages": ["libraries/py/api"]
}
]
},
@@ -423,15 +408,11 @@
},
{
"group": "Nuxt",
- "pages": [
- "libraries/nuxt/overview"
- ]
+ "pages": ["libraries/nuxt/overview"]
},
{
"group": "Rust",
- "pages": [
- "libraries/rs/overview"
- ]
+ "pages": ["libraries/rs/overview"]
},
{
"group": "Springboot",
@@ -474,4 +455,4 @@
"codeblocks": "system"
},
"theme": "maple"
-}
\ No newline at end of file
+}