# Overview Source: https://unkey.com/docs/analytics/overview Unkey tracks everything for you Consumption based billing for APIs is getting more and more popular, but it's tedious to build in house. For low frequency events, it's quite possible to emit usage events directly to Stripe or similar, but this becomes very noisy quickly. Furthermore if you want to build end-user facing or internal analytics, you need to be able to query the events from Stripe, which often does not provide the granularity required. Most teams end up without end-user facing analytics, or build their own system to store and query usage metrics. Since Unkey already stores and aggregates verification events by time, outcome and identity, we can offer this data via an API. ## Available data Unkey stores an event for every single verification, the relevent fields are described below: | Data | Type | Explanation | | -------------- | ------------- | -------------------------------------------------------------------------------------- | | `request_id` | String | Each request has a unique id, making it possible to retrieve later. | | `time` | Int64 | A unix milli timestamp. | | `key_space_id` | String | Each workspace may have multiple key spaces. Each API you create has its own keyspace. | | `key_id` | String | The individual key being verified. | | `outcome` | String | The outcome of the verification. `VALID`, `RATE_LIMITED` etc. | | `identity_id` | String | The identity connected to this key. | | `tags` | Array(String) | Arbitrary tags you may add during the verification to filter later. | We can return this data aggregated by `hour`, `day`, `month`, `tag`, `tags`, `identity`, `key` and `outcome`. As well as filter by `identity_id`, `key_space_id`, `key_id`, `tags`, `outcome`, `start` and `end` time. ## Example For an internal dashboard you want to find the top 5 users of a specific endpoint. In order to let Unkey know about the endpoint, you specify it as a tag when verifying keys: ```bash Tagging a verification {6} curl -XPOST 'https://api.unkey.dev/v1/keys.verifyKey' \ -H 'Content-Type: application/json' \ -d '{ "key": "", "apiId": "api_", "tags": [ "path=/my/endpoint" ], }' ``` You can now query `api.unkey.dev/v1/analytics.getVerifications` via query parameters. While we can't provide raw SQL access, we wanted to stay as close to SQL semantics as possible, so you didn't need to learn a new concept and to keep the translation layer simple. | Name | Value | Explanation | | --------- | --------------------------------- | ------------------------------------------------------------------------------ | | `start` | 1733749385000 | A unix milli timestamp to limit the query to a specific time frame. | | `end` | 1736431397000 | A unix milli timestamp to limit the query to a specific time frame. | | `apiId` | api\_262b3iR7gkmP7aUyZ24uihcijsCe | The API ID to filter keys. | | `groupBy` | identity | We're not interested in individual keys, but the user/org. | | `orderBy` | total | We want to see the most active users, by how many verifications they're doing. | | `order` | desc | We're ordering from most active to least active user. | | `limit` | 5 | Only return the top 5. | Below is a curl command putting everythign together: ```bash curl 'https://api.unkey.dev/v1/analytics.getVerifications?start=1733749385000&end=1736431397000&apiId=api_262b3iR7gkmP7aUyZ24uihcijsCe&groupBy=identity&orderBy=total&order=desc&limit=5' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ' ``` You'll receive a json response with a breakdown of each outcome, per identity ordered by `total`. ```json First Row [ { "valid": 186, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 184, "unauthorized": 0, "disabled": 182, "insufficientPermissions": 0, "expired": 0, "total": 552, "apiId": "api_262b3iR7gkmP7aUyZ24uihcijsCe", "identity": { "id": "test_2ipPuAgat7xuVNGpK6AuPQ2Lbk11", "externalId": "user_2rNBR4YXxKwzM8bzVrCR5q6dFlc" } }, ... ] ``` ```json Full Response [ { "valid": 186, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 184, "unauthorized": 0, "disabled": 182, "insufficientPermissions": 0, "expired": 0, "total": 552, "apiId": "api_262b3iR7gkmP7aUyZ24uihcijsCe", "identity": { "id": "test_2ipPuAgat7xuVNGpK6AuPQ2Lbk11", "externalId": "user_2rNBR4YXxKwzM8bzVrCR5q6dFlc" } }, { "valid": 190, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 161, "unauthorized": 0, "disabled": 200, "insufficientPermissions": 0, "expired": 0, "total": 551, "apiId": "api_262b3iR7gkmP7aUyZ24uihcijsCe", "identity": { "id": "test_2ipPuAiGJ3L3TUNKA6gp5eLeuyj7", "externalId": "user_2rLz6cM63ZQ2v3IU0mryKbHetjK" } }, { "valid": 197, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 154, "unauthorized": 0, "disabled": 200, "insufficientPermissions": 0, "expired": 0, "total": 551, "apiId": "api_262b3iR7gkmP7aUyZ24uihcijsCe", "identity": { "id": "test_2ipPuAwJVE4Hdet3dyEpYreP8ob7", "externalId": "user_2rLwFchrbyIDb4LUfFp4CpTG0L3" } }, { "valid": 191, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 184, "unauthorized": 0, "disabled": 171, "insufficientPermissions": 0, "expired": 0, "total": 546, "apiId": "api_262b3iR7gkmP7aUyZ24uihcijsCe", "identity": { "id": "test_2ipPuB23PVchmbkt9mMjjcpvLM8N", "externalId": "user_2rLwCGvQKtnfnemH8HTL4cxWBFo" } }, { "valid": 207, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 171, "unauthorized": 0, "disabled": 162, "insufficientPermissions": 0, "expired": 0, "total": 540, "apiId": "api_262b3iR7gkmP7aUyZ24uihcijsCe", "identity": { "id": "test_2ipPuApEvEAXJo9UParPL6inHLLJ", "externalId": "user_2rLDPPVfeNB2hn1ARMh2808CdwG" } } ] ``` # Quickstarts Source: https://unkey.com/docs/analytics/quickstarts Power your own dashboard, reports or usage-based billing These scenarios should give you a good starting point to understand what is possible and what you need to do. They are in no particular order and don't build upon each other. We are using cURL here for demo purposes, but you can use any of our [SDKs](/libraries) for this as well. Almost all query parameters can be combined to build powerful queries. If you run into issues or something doesn't seem possible, please get in touch, so we can figure it out together: [support@unkey.dev](mailto:support@unkey.dev) Detailed explanations about each individual parameter can be found in the [api-reference](/api-reference/analytics/get_verifications). ## User's usage over the past 24h Assuming you have an identity with `externalId=user_123` and an API with `apiId=api_123`. ```bash curl 'https://api.unkey.dev/v1/analytics.getVerifications?start=1736673687000&end=1736760087000&externalId=user_123&groupBy=hour&apiId=api_123' \ -H 'Authorization: Bearer unkey_XXX' ``` This will return 24 elements, one per hour over the last 24h. Each element tells you about the outcomes of verifications in that interval. ```json [ { "time": 1736672400000, "valid": 15125, "notFound": 0, "forbidden": 0, "usageExceeded": 1225, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 16350 }, { "time": 1736676000000, "valid": 765, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 765 }, ... 21 elements omited { "time": 1736755200000, "valid": 20016, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 51, "total": 20067 } ] ``` ## Daily usage of a user per key in the last month Assuming you have an identity with `externalId=user_123` and an API with `apiId=api_123`. ```bash curl 'https://api.unkey.dev/v1/analytics.getVerifications?start=1734168087000&end=1736760087000&externalId=user_123&groupBy=key&groupBy=day&apiId=api_123' \ -H 'Authorization: Bearer unkey_XXX' ``` This returns 1 element per active key per day and includes the keyId. ```json [ // ... { "time": 1736726400000, "valid": 13, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 10, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 23, "keyId": "key_2zeYsLbpULnEUsvYeFGMeJzACp4j" }, { "time": 1736726400000, "valid": 5, "notFound": 0, "forbidden": 0, "usageExceeded": 6, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 11, "keyId": "key_2zeViCGkJpu5zQ8G12jcBoXWy4KH" } ] ``` ## Total usage per month for an identity Assuming you have an identity with `externalId=user_123` and an API with `apiId=api_123`. You should set your `start` to the beginning of the month and `end` to now or end of the month. ```bash curl 'https://api.unkey.dev/v1/analytics.getVerifications?start=1734168087000&end=1736760087000&externalId=user_123&groupBy=month&apiId=api_123' \ -H 'Authorization: Bearer unkey_XXX' ``` This returns one element per month. ```json [ { "time": 1733011200000, "valid": 1356136098, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 925255, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 1357061353 } ] ``` ## Showing usage in the current billing period If you want to show a guage or similar to your user about their consumption in the current billing period. ```bash curl 'https://api.unkey.dev/v1/analytics.getVerifications?start=1734168087000&end=1736760087000&externalId=user_123&groupBy=day&apiId=api_123' \ -H 'Authorization: Bearer unkey_XXX' ``` This will return one element per day, which you can either display in a chart, or sum up to have a total value. ```json [ // ... { "time": 1736553600000, "valid": 98267, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 6816, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 105083 }, { "time": 1736640000000, "valid": 20125, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 2525, "unauthorized": 0, "disabled": 6261, "insufficientPermissions": 0, "expired": 0, "total": 28911 } ] ``` ## Internal dashboard showing top 10 users by API usage over the past 30 days ```bash curl 'https://api.unkey.dev/v1/analytics.getVerifications?start=1734168087000&end=1736760087000&orderBy=total&order=desc&limit=10&groupBy=identity&apiId=api_123' \ -H 'Authorization: Bearer unkey_XXX' ``` Returns 10 elements, ordered from most total verifications to least. Each element includes the `identityId` as well as the `externalId` for your reference. ```json [ { "identity": { "id": "id_123", "externalId": "user_123"}, "valid": 54, "notFound": 0, "forbidden": 3, "usageExceeded": 6, "rateLimited": 10, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 73 }, { "identity": { "id": "id_456", "externalId": "user_6dg"}, "valid": 24, "notFound": 0, "forbidden": 1, "usageExceeded": 32, "rateLimited": 10, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 67 }, ... ] ``` ## Filter by tags Find out how many verifications were done, where the tag `myTag` was specified. You can combine this with other parameters to group by days for example. You can provide multiple tags by providing them as separate query paramters: `?tag=myTag&tag=myOthertag`. Filtering multiple tags is a logical `OR`. The result includes all verifications where at least one of the filtered tags was specified. ```bash curl 'https://api.unkey.dev/v1/analytics.getVerifications?start=1734168087000&end=1736760087000&tag=myTag&apiId=api_123' \ -H 'Authorization: Bearer unkey_XXX' ``` This returns 1 element, a sum of all verifications in the selected time, where the tag `myTag` was specified. ```json [ { "valid": 5, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 5 } ] ``` ## Filter by key This only includes verifications of a specific key. You can provide multiple keyIds to filter verifications of any one of those keys. ```bash curl 'https://api.unkey.dev/v1/analytics.getVerifications?start=1734168087000&end=1736760087000&keyId=key_123&apiId=api_123' \ -H 'Authorization: Bearer unkey_XXX' ``` ```json [ { "valid": 14, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 10, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 24 } ] ``` ## Grouping by tags To understand usage across your tags, you can group by tags, breaking down all verifications and summing them up per tag combination. Note this is plural: `&groupBy=tags`. ```bash curl 'https://api.unkey.dev/v1/analytics.getVerifications?start=1734168087000&end=1736760087000&groupBy=tags&apiId=api_123' \ -H 'Authorization: Bearer unkey_XXX' ``` You'll receive an array of elements. Each element corresponds to one tag combination. ```json [ { "valid": 50, "notFound": 0, "forbidden": 3, "usageExceeded": 6, "rateLimited": 10, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 69, "tags": [] // these did not have tags specified }, { "valid": 1, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 1, "tags": [ "a", "b" ] }, { "valid": 2, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 2, "tags": [ "a", "c" ] }, { "valid": 2, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 2, "tags": [ "a" ] } ] ``` ## Breakdown by individual tag If you want to see usage for an individual tag, regardless of combination with other tags, you can group by tag. Note this is singular `&groupBy=tag`. ```bash curl 'https://api.unkey.dev/v1/analytics.getVerifications?start=1734168087000&end=1736760087000&groupBy=tag&apiId=api_123' \ -H 'Authorization: Bearer unkey_XXX' ``` You'll receive one element per unique tag. ```json [ { "valid": 1, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 1, "tag": "b" }, { "valid": 2, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 2, "tag": "c" }, { "valid": 5, "notFound": 0, "forbidden": 0, "usageExceeded": 0, "rateLimited": 0, "unauthorized": 0, "disabled": 0, "insufficientPermissions": 0, "expired": 0, "total": 5, "tag": "a" } ] ``` # Get Verifications Source: https://unkey.com/docs/api-reference/analytics/get_verifications get /v1/analytics.getVerifications To use this endpoint, your root key must have the `api.*.read_api` permission. Retrieve usage data from unkey to power your dashboards, reports or usage-based billing. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jan 01 2025 | Introduced endpoint | # Create an API Source: https://unkey.com/docs/api-reference/apis/create post /v1/apis.createApi ## Changelog | Date | Changes | | ----------- | ------------------- | | Dec 06 2023 | Introduced endpoint | # Delete an API Source: https://unkey.com/docs/api-reference/apis/delete post /v1/apis.deleteApi Permanently delete an API and revoke all keys associated with it ## Changelog | Date | Changes | | ----------- | ------------------- | | Dec 06 2023 | Introduced endpoint | # Delete all keys of an API Source: https://unkey.com/docs/api-reference/apis/delete-keys post /v1/apis.deleteKeys ## Changelog | Date | Changes | | ----------- | ------------------- | | May 26 2024 | Introduced endpoint | # Retrieve an API Source: https://unkey.com/docs/api-reference/apis/get get /v1/apis.getApi ## Changelog | Date | Changes | | ----------- | ------------------- | | Dec 06 2023 | Introduced endpoint | # List keys for an API Source: https://unkey.com/docs/api-reference/apis/list-keys get /v1/apis.listKeys ## Changelog | Date | Changes | | ----------- | ----------------------------- | | Dec 06 2023 | Introduced endpoint | | May 15 2024 | Return updatedAt timestamp | | Aug 01 2024 | Return identities | | Aug 01 2024 | Added filtering by externalId | # Authentication Source: https://unkey.com/docs/api-reference/authentication Securely authenticating with the Unkey API Almost all Unkey API endpoints require authentication using a root key. Root keys provide access to your Unkey resources based on their assigned permissions. ## Bearer Authentication Authentication is performed using HTTP Bearer authentication in the `Authorization` header: ```bash Authorization: Bearer unkey_1234567890 ``` Example request: ```bash curl -X POST "https://api.unkey.dev/v1/keys.createKey" \ -H "Authorization: Bearer unkey_1234567890" \ -H "Content-Type: application/json" \ -d '{ "apiId": "api_1234" }' ``` ## Security Best Practices Never expose your root key in client-side code or include it in public repositories. For frontend applications, always use a backend server to proxy requests to the Unkey API. ## Root Key Management Root keys can be created and managed through the Unkey dashboard. We recommend: 1. **Using Different Keys for Different Environments**: Maintain separate root keys for development, staging, and production 2. **Rotating Keys Regularly**: Create new keys periodically and phase out old ones 3. **Setting Clear Key Names**: Name your keys according to their use case for better manageability ## Key Permissions System Unkey implements a sophisticated RBAC (Role-Based Access Control) system for root keys. Permissions are defined as tuples of: * **ResourceType**: The category of resource (api, ratelimit, rbac, identity) * **ResourceID**: The specific resource instance * **Action**: The operation to perform on that resource ### Available Resource Types | Resource Type | Description | | ------------- | ------------------------------------------------- | | `api` | API-related resources, such as endpoints and keys | | `ratelimit` | Rate limiting resources and configuration | | `rbac` | Permissions and roles management | | `identity` | User and identity management | ### Permission Examples Specific permission to manage a single API: ``` api.api_1234.read_api api.api_1234.update_api ``` Wildcard permission to manage all rate limit namespaces: ``` ratelimit.*.create_namespace ratelimit.*.read_namespace ``` When creating root keys, you can specify exactly what actions they're allowed to perform. ## Authentication Errors If your authentication fails, you'll receive a 401 Unauthorized or 403 Forbidden response with an error message: ```json { "meta": { "requestId": "req_abc123xyz789" }, "error": { "title": "Unauthorized", "detail": "The provided root key is invalid or has been revoked", "status": 401, "type": "https://unkey.com/docs/errors/unauthorized" } } ``` If your key is valid but lacks sufficient permissions, you'll receive a 403 Forbidden response: ```json { "meta": { "requestId": "req_abc123xyz789" }, "error": { "title": "Forbidden", "detail": "Your key does not have the required 'api.api_1234.update_api' permission", "status": 403, "type": "https://unkey.com/docs/errors/forbidden" } } ``` Common authentication issues include: * Missing the Authorization header * Invalid key format * Revoked or expired root key * Using a key with insufficient permissions # Overview Source: https://unkey.com/docs/api-reference/errors-v2/overview Understanding Unkey's structured error system These errors are only for the v2 API, which is not yet GA. ## Introduction Unkey's error system uses a structured approach to organize and identify errors across the platform. This system makes it easier to understand, debug, and handle errors consistently. ## Error Code Format All Unkey error codes follow a consistent URN-like format: ``` err:system:category:specific ``` For example: `err:unkey:authentication:missing` This format breaks down as follows: * **err**: Standard prefix for all error codes * **system**: The service area or responsibility domain (e.g., unkey, user) * **category**: The error type or classification (e.g., authentication, data) * **specific**: The exact error condition (e.g., missing, malformed) ## Systems The "system" component identifies where the error originated: * **unkey**: Errors originating from Unkey's internal systems * **github**: Errors related to GitHub integration * **aws**: Errors related to AWS integration ## Categories The "category" component provides a second level of classification, for example: * **authentication**: Errors related to the authentication process * **authorization**: Errors related to permissions and access control * **application**: Errors related to application operations and system integrity * **data**: Errors related to data operations and resources * **limits**: Rate limiting or quota-related errors ## Error Response Format When an error occurs, the API returns a consistent JSON response format: ```json { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "Authentication credentials were not provided", "status": 401, "title": "Unauthorized", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/authentication/missing" } } ``` Key fields: * **requestId**: Unique identifier for the request (important for support) * **detail**: Human-readable explanation of the error * **status**: HTTP status code * **title**: Short summary of the error type * **type**: URL to detailed documentation about this error ## Documentation Integration All error codes have a corresponding documentation page accessible via the `type` URL in the error response. These pages provide detailed information about: * What caused the error * How to fix the issue * Common mistakes that lead to this error * Related errors you might encounter # err:unkey:application:assertion_failed Source: https://unkey.com/docs/api-reference/errors-v2/unkey/application/assertion_failed A runtime assertion or invariant check failed ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "A system integrity check failed while processing your request", "status": 500, "title": "Internal Server Error", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/application/assertion_failed" } } ``` ## What Happened? This error occurs when Unkey's internal system detects an inconsistency or violation of its expected invariants during the processing of your request. Unlike validation errors which occur when your input is invalid, assertion failures happen when the system's internal state doesn't match what was expected. Possible causes include: * Data corruption or inconsistency in Unkey's database * Bugs in Unkey's business logic * Race conditions or timing issues * System state that violates core assumptions * Incompatible changes between different parts of the system This type of error is generally not caused by anything you did wrong in your request, but rather indicates an internal issue with Unkey's system integrity. ## How To Fix Since this is an internal system error, there's usually nothing you can directly do to fix it. However, you can try the following: 1. **Retry the request**: Some assertion failures may be due to temporary conditions that resolve themselves 2. **Contact Unkey support**: Report the error with the request ID to help Unkey address the underlying issue 3. **Check for workarounds**: In some cases, using a different API endpoint or approach might avoid the issue When contacting support, be sure to include: * The full error response, including the request ID * The API endpoint you were calling * The request payload (with sensitive information redacted) * Any patterns you've noticed (e.g., if it happens consistently or intermittently) ## Important Notes * Assertion failures indicate bugs or data integrity issues that Unkey needs to fix * Unlike many other errors, changing your request is unlikely to resolve the issue * These errors are typically logged and monitored by Unkey's engineering team * If you encounter this error consistently, there may be an underlying issue with your account data ## Related Errors * [err:unkey:application:unexpected\_error](./unexpected_error) - A more general internal error * [err:unkey:application:service\_unavailable](./service_unavailable) - When a service is temporarily unavailable # err:unkey:application:invalid_input Source: https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input Client provided input that failed validation ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The request contains invalid input that failed validation", "status": 400, "title": "Bad Request", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/application/invalid_input", "errors": [ { "location": "body.limit", "message": "must be greater than or equal to 1", "fix": "Provide a limit value of at least 1" } ] } } ``` ## What Happened? This error occurs when your request contains input data that doesn't meet Unkey's validation requirements. This could be due to missing required fields, values that are out of allowed ranges, incorrectly formatted data, or other validation failures. Common validation issues include: * Missing required fields * Values that exceed minimum or maximum limits * Strings that don't match required patterns * Invalid formats for IDs, emails, or other structured data * Type mismatches (e.g., providing a string where a number is expected) Here's an example of a request that would trigger this error: ```bash # Attempting to create a rate limit with an invalid limit value of 0 curl -X POST https://api.unkey.com/v2/ratelimit.limit \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "namespace": "api.requests", "identifier": "user_123", "limit": 0, "duration": 60000 }' ``` ## How To Fix To fix this error, carefully review the error details provided in the response. The `errors` array contains specific information about what failed validation: 1. Check the `location` field to identify which part of your request is problematic 2. Read the `message` field for details about why validation failed 3. Look at the `fix` field (if available) for guidance on how to correct the issue 4. Modify your request to comply with the validation requirements Here's the corrected version of our example request: ```bash # Corrected request with a valid limit value curl -X POST https://api.unkey.com/v2/ratelimit.limit \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "namespace": "api.requests", "identifier": "user_123", "limit": 100, "duration": 60000 }' ``` ## Common Mistakes * **Ignoring schema requirements**: Not checking the API documentation for field requirements * **Range violations**: Providing values outside of allowed ranges (too small, too large) * **Format errors**: Not following the required format for IDs, emails, or other structured data * **Missing fields**: Omitting required fields in API requests * **Type errors**: Sending the wrong data type (e.g., string instead of number) ## Related Errors * [err:unkey:application:assertion\_failed](./assertion_failed) - When a runtime assertion or invariant check fails * [err:unkey:application:protected\_resource](./protected_resource) - When attempting to modify a protected resource # err:unkey:application:protected_resource Source: https://unkey.com/docs/api-reference/errors-v2/unkey/application/protected_resource Attempt to modify a protected resource ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The resource you are attempting to modify is protected and cannot be changed", "status": 403, "title": "Forbidden", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/application/protected_resource" } } ``` ## What Happened? This error occurs when you attempt to modify or delete a resource that is marked as protected in the Unkey system. Protected resources have a special status that prevents them from being changed or removed, typically because they are system resources, defaults, or otherwise critical to proper system operation. Common scenarios that trigger this error: * Attempting to delete a default API or workspace * Trying to modify system-created roles or permissions * Attempting to change protected settings or configurations * Trying to remove or alter resources that are required for system integrity Here's an example of a request that might trigger this error: ```bash # Attempting to delete a protected default API curl -X DELETE https://api.unkey.com/v1/apis.deleteApi \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "apiId": "api_default_protected" }' ``` ## How To Fix Since protected resources are deliberately shielded from modification, the solution is usually to work with or around them rather than trying to change them: 1. **Work with the protected resource**: Use the resource as-is and build your workflows around it 2. **Create a new resource**: Instead of modifying a protected resource, create a new one with your desired configuration 3. **Use alternatives**: Look for alternative ways to achieve your goal without modifying protected resources 4. **Contact support**: If you believe you have a legitimate need to modify a protected resource, contact Unkey support For example, instead of deleting a protected API, you might create a new one: ```bash curl -X POST https://api.unkey.com/v2/apis.createApi \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "name": "My Custom API" }' ``` ## Important Notes * Protected resources are designated as such for system stability and security reasons * Even with admin or owner permissions, protected resources typically cannot be modified * This protection is separate from permission-based restrictions and applies even to workspace owners * The protection status of a resource is not typically exposed in API responses until you try to modify it ## Related Errors * [err:unkey:authorization:forbidden](../authorization/forbidden) - When an operation is not allowed for policy reasons * [err:unkey:authorization:insufficient\_permissions](../authorization/insufficient_permissions) - When you lack permissions for an operation # err:unkey:application:service_unavailable Source: https://unkey.com/docs/api-reference/errors-v2/unkey/application/service_unavailable A service is temporarily unavailable ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The service is temporarily unavailable. Please try again later.", "status": 503, "title": "Service Unavailable", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/application/service_unavailable" } } ``` ## What Happened? This error occurs when a component of the Unkey platform is temporarily unavailable or unable to process your request. Unlike an unexpected error, this is a known state where the system has detected that it cannot currently provide the requested service. Possible causes of this error: * Scheduled maintenance * High load or capacity issues * Dependent service outages * Regional infrastructure problems * Database overload or maintenance Here's an example of a request that might receive this error during a service disruption: ```bash curl -X POST https://api.unkey.com/v1/keys.createKey \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "apiId": "api_123abc", "name": "My API Key" }' ``` ## How To Fix Since this is a temporary service issue, the best approach is to wait and retry. Here are some strategies: 1. **Implement retry logic**: Add automatic retries with exponential backoff to your code 2. **Check service status**: Visit the Unkey status page for updates on service availability 3. **Try alternate regions**: If Unkey offers region-specific endpoints, try an alternate region 4. **Wait and retry manually**: If it's a one-time operation, simply try again later Here's an example of a robust retry strategy: ```bash # Bash script with retry logic max_attempts=5 attempt=0 backoff_time=1 while [ $attempt -lt $max_attempts ]; do response=$(curl -s -w "\n%{http_code}" \ -X POST https://api.unkey.com/v1/keys.createKey \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "apiId": "api_123abc", "name": "My API Key" }') http_code=$(echo "$response" | tail -n1) body=$(echo "$response" | sed '$ d') if [ $http_code -eq 503 ]; then attempt=$((attempt+1)) if [ $attempt -eq $max_attempts ]; then echo "Service still unavailable after $max_attempts attempts" exit 1 fi echo "Service unavailable, retrying in $backoff_time seconds... (Attempt $attempt/$max_attempts)" sleep $backoff_time backoff_time=$((backoff_time*2)) else echo "$body" exit 0 fi done ``` ## Important Notes * This error is temporary, and the service will typically recover automatically * For critical applications, implement circuit breakers to prevent cascading failures * If the service remains unavailable for an extended period, check Unkey's status page or contact support * Include the `requestId` from the error response when contacting support ## Related Errors * [err:unkey:application:unexpected\_error](./unexpected_error) - When an unhandled error occurs * [err:unkey:authorization:workspace\_disabled](../authorization/workspace_disabled) - When the workspace is disabled (a different type of unavailability) # err:unkey:application:unexpected_error Source: https://unkey.com/docs/api-reference/errors-v2/unkey/application/unexpected_error An unhandled or unexpected error occurred ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "An unexpected error occurred while processing your request", "status": 500, "title": "Internal Server Error", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/application/unexpected_error" } } ``` ## What Happened? This error occurs when the Unkey system encounters an internal error that wasn't anticipated or couldn't be handled gracefully. This is generally not caused by anything you did wrong in your request, but rather indicates an issue within Unkey's systems. Possible causes of this error: * Temporary infrastructure issues * Database connectivity problems * Bugs in the Unkey service * Resource constraints or timeouts * Unexpected edge cases not handled by the application logic Here's an example of a request that might trigger this error if there's an internal issue: ```bash # A valid request that could trigger an unexpected error if there's an internal issue curl -X POST https://api.unkey.com/v1/keys.createKey \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "apiId": "api_123abc", "name": "My API Key" }' ``` ## How To Fix Since this is an internal error, there's usually little you can do to directly fix it, but you can try the following: 1. **Retry the request**: Many unexpected errors are temporary and will resolve on a retry 2. **Check Unkey status**: Visit the Unkey status page to see if there are any ongoing service issues 3. **Contact support**: If the error persists, contact Unkey support with your request ID 4. **Implement retry logic**: For critical operations, implement exponential backoff retry logic in your code Here's an example of implementing retry logic with exponential backoff: ```javascript // Pseudocode for retry with exponential backoff async function retryWithBackoff(fn, maxRetries = 3, baseDelay = 300) { let retries = 0; while (true) { try { return await fn(); } catch (error) { if (error.status !== 500 || retries >= maxRetries) { throw error; // Either not a 500 error or we've exceeded retries } // Exponential backoff with jitter const delay = baseDelay * Math.pow(2, retries) * (0.8 + Math.random() * 0.4); console.log(`Retrying after ${delay}ms (attempt ${retries + 1}/${maxRetries})`); await new Promise(resolve => setTimeout(resolve, delay)); retries++; } } } ``` ## Important Notes * Always include the `requestId` when contacting support about this error * This error may indicate a bug in Unkey's systems that needs to be fixed * Unlike most other errors, this one usually can't be resolved by changing your request * If you encounter this error consistently with a specific API call, there may be an edge case that Unkey's team needs to address ## Related Errors * [err:unkey:application:service\_unavailable](./service_unavailable) - When a service is temporarily unavailable # err:unkey:authentication:key_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/authentication/key_not_found The authentication key was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The provided API key was not found", "status": 401, "title": "Unauthorized", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/authentication/key_not_found" } } ``` ## What Happened? This error occurs when you've provided a properly formatted API key in your request to the Unkey API, but the key doesn't exist in Unkey's system. The key might have been deleted, revoked, or you might be using an incorrect key. Common causes include: * Using an API key that has been deleted * Using an API key from a different workspace or environment * Typographical errors when entering the key * Using a test key in production or vice versa Here's an example of a request with a non-existent API key: ```bash # Request to Unkey API with a non-existent key curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_NONEXISTENT_KEY" ``` ## How To Fix To fix this error, you need to use a valid API key when making requests to the Unkey API: 1. **Check your Unkey dashboard**: Verify you're using the correct Unkey API key from the [Unkey dashboard](https://app.unkey.com) 2. **Create a new key if needed**: If your key was deleted, create a new one 3. **Use the correct environment**: Make sure you're using the appropriate key for your environment (development, production, etc.) Here's how to check and use the correct Unkey API key: 1. Log in to your Unkey dashboard 2. Navigate to the API keys section 3. Copy the appropriate API key for your environment 4. Use the key in your request as shown below ```bash curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_VALID_API_KEY" ``` ## Common Mistakes * **Using revoked Unkey keys**: API keys that have been revoked will return this error * **Environment mismatch**: Using development keys in production or vice versa * **Workspace confusion**: Using keys from one workspace in another workspace's API calls * **Copy-paste errors**: Inadvertently omitting part of the key when copying * **Expired keys**: Keys that have expired will return this error * **Using demo keys**: Using example keys from documentation ## Related Errors * [err:unkey:authentication:missing](./missing) - When no authentication credentials are provided * [err:unkey:authentication:malformed](./malformed) - When the API key is provided but formatted incorrectly # err:unkey:authentication:malformed Source: https://unkey.com/docs/api-reference/errors-v2/unkey/authentication/malformed Authentication credentials were incorrectly formatted ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "Authentication credentials were incorrectly formatted", "status": 401, "title": "Unauthorized", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/authentication/malformed" } } ``` ## What Happened? This error occurs when your request includes authentication credentials, but they are not formatted correctly. The Unkey API expects API keys to be provided in a specific format in the Authorization header. Common causes include: * Missing the "Bearer" prefix before your API key * Including extra spaces or characters * Using incorrect casing (e.g., "bearer" instead of "Bearer") * Providing a malformed or truncated API key Here's an example of a request with incorrectly formatted credentials: ```bash # Missing the "Bearer" prefix curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" \ -H "Authorization: unkey_YOUR_API_KEY" ``` ## How To Fix To fix this error, ensure your Authorization header follows the correct format: 1. **Use the correct format**: Ensure your Authorization header follows the format `Bearer unkey_YOUR_API_KEY` 2. **Check for extra spaces or characters**: Make sure there are no invisible characters or line breaks 3. **Verify the API key format**: Your Unkey API key should start with `unkey_` Here's the correctly formatted request: ```bash curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" ``` When properly authenticated, you'll receive a successful response like this: ```json { "meta": { "requestId": "req_8f7g6h5j4k3l2m1n" }, "data": { "keys": [ { "keyId": "key_123abc456def", "name": "Production API Key" } ] } } ``` ## Common Mistakes * **Authorization header format**: Must be exactly `Bearer unkey_YOUR_API_KEY` with a single space after "Bearer" * **Incorrect casing**: Using "bearer" instead of "Bearer" * **API key format**: Your Unkey API key should start with `unkey_` and contain no spaces * **Using wrong key type**: Ensure you're using a root key for management API calls * **Copying errors**: Check for invisible characters or line breaks that might have been copied * **Extra characters**: Including quotes or other characters around the API key * **Truncated keys**: Accidentally cutting off part of the API key when copying ## Related Errors * [err:unkey:authentication:missing](./missing) - When no authentication credentials are provided * [err:unkey:authentication:key\_not\_found](./key_not_found) - When the provided API key doesn't exist # err:unkey:authentication:missing Source: https://unkey.com/docs/api-reference/errors-v2/unkey/authentication/missing Authentication credentials were not provided in the request ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "Authentication credentials were not provided", "status": 401, "title": "Unauthorized", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/authentication/missing" } } ``` ## What Happened? This error occurs when you make a request to the Unkey API without including your API key in the Authorization header. The Unkey API requires authentication for most endpoints to verify your identity and permissions. Here's an example of a request that would trigger this error: ```bash # Request to Unkey API without an API key curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" ``` Authentication is required to: * Verify your identity * Ensure you have permission to perform the requested operation * Track usage and apply appropriate rate limits * Maintain security and audit trails ## How To Fix To fix this error, you need to include your Unkey API key in the Authorization header of your request: 1. **Get your Unkey API key**: Obtain your API key from the [Unkey dashboard](https://app.unkey.com) 2. **Add the Authorization header**: Include your Unkey API key with the format `Bearer unkey_YOUR_API_KEY` Here's the corrected request: ```bash curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" ``` When properly authenticated, you'll receive a successful response like this: ```json { "meta": { "requestId": "req_8f7g6h5j4k3l2m1n" }, "data": { "keys": [ { "keyId": "key_123abc456def", "name": "Production API Key" } ] } } ``` ## Common Mistakes * **Missing the `Bearer` prefix**: Unkey requires the format `Bearer unkey_YOUR_API_KEY` with a space after "Bearer" * **Headers lost in proxies**: Some proxy servers or API gateways might strip custom headers * **Expired or revoked keys**: Using keys that are no longer valid * **Wrong environment**: Using development keys in production or vice versa ## Related Errors * [err:unkey:authentication:malformed](./malformed) - When the API key is provided but formatted incorrectly * [err:unkey:authentication:key\_not\_found](./key_not_found) - When the provided API key doesn't exist # err:unkey:authorization:forbidden Source: https://unkey.com/docs/api-reference/errors-v2/unkey/authorization/forbidden The operation is not allowed ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "This operation is not allowed", "status": 403, "title": "Forbidden", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/authorization/forbidden" } } ``` ## What Happened? This error occurs when you attempt an operation that is prohibited by Unkey's platform policies, even if your API key has high-level permissions. Unlike the "insufficient\_permissions" error which relates to permission roles, this error indicates that the operation itself is not allowed regardless of permissions. Common scenarios that trigger this error: * Trying to perform operations on protected or system resources * Attempting to modify resources that are in a state that doesn't allow modifications * Trying to exceed account limits or quotas * Performing operations that violate platform policies Here's an example of a request that might trigger this error: ```bash # Attempting to delete a protected system resource curl -X POST https://api.unkey.com/v2/apis.deleteApi \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_ADMIN_KEY" \ -d '{ "apiId": "api_system_protected" }' ``` ## How To Fix This error indicates a fundamental restriction rather than a permission issue. The operation you're trying to perform may be: 1. **Not supported by the Unkey platform**: Some operations are simply not available 2. **Blocked due to your account's current state or limitations**: Your account may not have access to certain features 3. **Prevented by safety mechanisms**: System protections may prevent certain destructive operations Possible solutions include: * **Check Unkey's documentation**: Understand which operations have fundamental restrictions * **Consider your account state**: Some operations may be blocked due to your account state or plan * **Use alternative approaches**: Find supported ways to accomplish similar goals * **If you're trying to modify a resource in a specific state**, check if it needs to be in a different state first * **If you're hitting account limits**, consider upgrading your plan * **Contact Unkey support** if you believe this restriction shouldn't apply to your use case ## Common Mistakes * **Attempting to modify system resources**: Some Unkey resources are protected and cannot be modified * **Order-dependent operations**: Trying to perform operations out of their required sequence * **Plan limitations**: Attempting operations not available on your current plan * **Resource state issues**: Trying to modify resources that are in a state that doesn't allow changes * **Ignoring documentation warnings**: Not reading warnings about restricted operations * **Testing security boundaries**: Deliberately trying to access protected resources * **Outdated documentation**: Following outdated documentation that suggests now-forbidden operations ## Related Errors * [err:unkey:authorization:insufficient\_permissions](./insufficient_permissions) - When the authenticated entity lacks specific permissions * [err:unkey:authorization:key\_disabled](./key_disabled) - When the authentication key is disabled * [err:unkey:authorization:workspace\_disabled](./workspace_disabled) - When the associated workspace is disabled # err:unkey:authorization:insufficient_permissions Source: https://unkey.com/docs/api-reference/errors-v2/unkey/authorization/insufficient_permissions The authenticated entity lacks sufficient permissions for the requested operation ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The authenticated API key does not have permission to perform this operation", "status": 403, "title": "Forbidden", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/authorization/insufficient_permissions" } } ``` ## What Happened? This error occurs when your API key is valid and properly authenticated, but it doesn't have the necessary permissions to perform the requested operation. In Unkey, different API keys can have different permission levels. Common scenarios that trigger this error: * Using a read-only key to perform write operations * Using a key limited to specific resources to access other resources * Attempting to access resources across workspaces with a workspace-scoped key * Using a key with limited permissions to perform administrative actions Here's an example of a request using a key with insufficient permissions: ```bash # Using a read-only key to create a new API key curl -X POST https://api.unkey.com/v1/keys.createKey \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_READ_ONLY_KEY" \ -d '{ "apiId": "api_123", "name": "New API Key" }' ``` ## How To Fix You need to use an API key with the appropriate permissions for the operation you're trying to perform. Here are some steps to resolve this issue: 1. **Check permissions**: Verify the permissions of your current Unkey API key in the [Unkey dashboard](https://app.unkey.com) 2. **Create a new key**: If needed, create a new Unkey API key with the required permissions 3. **Use role-based keys**: Consider using separate keys for different operations based on their permission requirements Here's an example using a key with the appropriate permissions: ```bash curl -X POST https://api.unkey.com/v1/keys.createKey \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_ADMIN_KEY" \ -d '{ "apiId": "api_123", "name": "New API Key" }' ``` ## Common Mistakes * **Using development keys in production**: Keys may have different permissions across environments * **Mixing key scopes**: Using a key scoped to one resource to access another * **Role misunderstanding**: Not understanding the specific permissions granted to each role * **Workspace boundaries**: Attempting to cross workspace boundaries with a limited key * **Permission level confusion**: Not understanding what operations require elevated permissions * **Expired or downgraded privileges**: Using a key whose permissions have been reduced since it was issued ## Related Errors * [err:unkey:authorization:forbidden](./forbidden) - When the operation is not allowed for policy reasons * [err:unkey:authorization:key\_disabled](./key_disabled) - When the authentication key is disabled # err:unkey:authorization:key_disabled Source: https://unkey.com/docs/api-reference/errors-v2/unkey/authorization/key_disabled The authentication key is disabled ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The API key used for authentication has been disabled", "status": 403, "title": "Forbidden", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/authorization/key_disabled" } } ``` ## What Happened? This error occurs when you try to use a disabled Unkey API key (one that starts with `unkey_`) to authenticate with the Unkey API. The key exists in the system but has been disabled and can no longer be used for authentication. Here's an example of a request that would trigger this error: ```bash # Request to Unkey API with a disabled key curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_DISABLED_KEY" ``` API keys can be disabled for various reasons: * Administrative action to revoke access * Security concerns or suspected compromise * Temporary deactivation during maintenance or investigation * Automated disabling due to suspicious activity * Usage policy violations ## How To Fix If you encounter this error when using the Unkey API, you have two options: 1. **Get a new Unkey root key**: If your key was permanently disabled, create a new API key with the appropriate permissions in the [Unkey dashboard](https://app.unkey.com/settings/root-keys) 2. **Re-enable your existing key**: If you have administrative access and the key was temporarily disabled, you can re-enable it through the dashboard To re-enable your Unkey root key: 1. Log in to your Unkey dashboard 2. Navigate to the API keys section 3. Search for the key you want to re-enable 4. Click "Enable" Then update your API calls to use the re-enabled key: ```bash curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_REACTIVATED_KEY" ``` ## Common Mistakes * **Using old or archived root keys**: Keys from previous projects or configurations may have been disabled * **Shared root keys**: When keys are shared among team members, they may be disabled by another administrator * **Security triggers**: Unusual usage patterns may automatically disable keys as a security precaution * **Environment confusion**: Using disabled staging/development keys in production environments * **Account status changes**: Keys may be disabled due to billing or account status changes * **Rotation policies**: Keys that should have been rotated according to security policies ## Related Errors * [err:unkey:authorization:insufficient\_permissions](./insufficient_permissions) - When the authenticated entity lacks sufficient permissions * [err:unkey:authorization:workspace\_disabled](./workspace_disabled) - When the associated workspace is disabled * [err:unkey:authentication:key\_not\_found](../authentication/key_not_found) - When the provided API key doesn't exist at all # err:unkey:authorization:workspace_disabled Source: https://unkey.com/docs/api-reference/errors-v2/unkey/authorization/workspace_disabled The associated workspace is disabled ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The workspace associated with this API key has been disabled", "status": 403, "title": "Forbidden", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/authorization/workspace_disabled" } } ``` ## What Happened? This error occurs when you attempt to use an Unkey API key that belongs to a disabled workspace. When a workspace is disabled in Unkey, all API keys associated with that workspace stop working, regardless of their individual status. Here's an example of a request that would trigger this error: ```bash # Request to Unkey API with a key from a disabled workspace curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_KEY_FROM_DISABLED_WORKSPACE" ``` A workspace might be disabled for various reasons: * Billing issues or unpaid invoices * Administrative action due to terms of service violations * At the workspace owner's request * During investigation of suspicious activity * As part of account closure process * Exceeding usage limits or quotas ## How To Fix If you encounter this error when using the Unkey API, you need to address the workspace issue: 1. **Check billing status**: If the workspace was disabled due to billing issues, settle any outstanding payments in the [Unkey dashboard](https://app.unkey.com/settings/billing) 2. **Contact workspace administrator**: If you're not the workspace administrator, contact them to determine why the workspace was disabled 3. **Contact Unkey support**: If you believe the workspace was disabled in error, or you need assistance resolving the issue, contact [Unkey support](mailto:support@unkey.dev) 4. **Use a key from a different workspace**: If you have access to multiple workspaces, you can temporarily use a key from an active workspace while resolving the issue Once the workspace is re-enabled, all API keys associated with it should become usable again (unless individually disabled). ## Common Mistakes * **Billing oversights**: Missed payment notifications can lead to workspace suspension * **Usage violations**: Excessive usage or pattern violations may trigger workspace disabling * **Administrative changes**: Organizational changes might lead to workspaces being temporarily disabled * **Using old workspaces**: Attempting to use keys from deprecated or archived workspaces * **Plan limitation violations**: Exceeding the limits of your current plan * **Account transfer issues**: Workspaces may be temporarily disabled during ownership transfers ## Related Errors * [err:unkey:authorization:key\_disabled](./key_disabled) - When the specific authentication key is disabled * [err:unkey:authorization:insufficient\_permissions](./insufficient_permissions) - When the authenticated entity lacks sufficient permissions * [err:unkey:data:workspace\_not\_found](../data/workspace_not_found) - When the requested workspace doesn't exist # err:unkey:data:api_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/api_not_found The requested API was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The requested API could not be found", "status": 404, "title": "Not Found", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/api_not_found" } } ``` ## What Happened? This error occurs when you're trying to perform an operation on an API that doesn't exist in the Unkey system. In Unkey, APIs are resources that you create to organize and manage your keys. Common scenarios that trigger this error: * Using an incorrect API ID in your requests * Referencing an API that has been deleted * Attempting to access an API in a workspace you don't have access to * Typos in API names when using name-based lookups Here's an example of a request that would trigger this error: ```bash # Attempting to create a key for a non-existent API curl -X POST https://api.unkey.com/v1/keys.createKey \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "apiId": "api_nonexistent", "name": "hello world" }' ``` ## How To Fix Verify that you're using the correct API ID and that the API still exists in your workspace: 1. List all APIs in your workspace to find the correct ID 2. Check if the API has been deleted and recreate it if necessary 3. Verify you're working in the correct workspace 4. Ensure proper permissions to access the API Here's how to list all APIs in your workspace: ```bash curl -X GET https://api.unkey.com/v1/apis.listApis \ -H "Authorization: Bearer unkey_YOUR_API_KEY" ``` If you need to create a new API, use the `apis.createApi` endpoint: ```bash curl -X POST https://api.unkey.com/v1/apis.createApi \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "name": "My New API" }' ``` ## Common Mistakes * **Copy-paste errors**: Using incorrect API IDs from documentation examples * **Deleted APIs**: Attempting to reference APIs that have been deleted * **Environment confusion**: Looking for an API in production that only exists in development * **Workspace boundaries**: Trying to access an API that exists in another workspace ## Related Errors * [err:unkey:data:workspace\_not\_found](./workspace_not_found) - When the requested workspace doesn't exist * [err:unkey:data:key\_not\_found](./key_not_found) - When the requested key doesn't exist * [err:unkey:authorization:insufficient\_permissions](../authorization/insufficient_permissions) - When you don't have permission to access an API # err:unkey:data:audit_log_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/audit_log_not_found The requested audit log was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The requested audit log could not be found", "status": 404, "title": "Not Found", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/audit_log_not_found" } } ``` ## What Happened? This error occurs when you're trying to retrieve or operate on a specific audit log entry that doesn't exist in the Unkey system. Audit logs record important actions and events that occur within your workspace. Common scenarios that trigger this error: * Using an incorrect audit log ID * Requesting an audit log entry that has been deleted or expired * Trying to access audit logs from a different workspace * Typographical errors in audit log identifiers Here's an example of a request that would trigger this error: ```bash # Attempting to get a non-existent audit log entry curl -X GET https://api.unkey.com/v1/audit.getLog \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "logId": "log_nonexistent" }' ``` ## How To Fix Verify that you're using the correct audit log ID and that the log entry still exists in your workspace: 1. Check the audit log ID in your request for typos or formatting errors 2. Use the list audit logs endpoint to find valid log IDs 3. Verify you're working in the correct workspace 4. Consider that audit logs might have a retention period after which they're automatically deleted Here's how to list recent audit logs in your workspace: ```bash curl -X GET https://api.unkey.com/v1/audit.listLogs \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "limit": 10 }' ``` ## Common Mistakes * **Expired logs**: Trying to access audit logs beyond the retention period * **Copy-paste errors**: Using incorrect log IDs from documentation examples * **Workspace boundaries**: Attempting to access logs from another workspace * **Permission issues**: Trying to access logs you don't have permission to view ## Related Errors * [err:unkey:authorization:insufficient\_permissions](../authorization/insufficient_permissions) - When you don't have permission to access audit logs * [err:unkey:data:workspace\_not\_found](./workspace_not_found) - When the requested workspace doesn't exist # err:unkey:data:identity_already_exists Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/identity_already_exists The requested identity already exists ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "An identity with this external ID already exists", "status": 409, "title": "Conflict", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/identity_already_exists" } } ``` ## What Happened? This error occurs when you're trying to create an identity with an external ID that already exists in your Unkey workspace. External IDs must be unique within a workspace to avoid confusion and maintain data integrity. Common scenarios that trigger this error: * Creating an identity with an external ID that's already in use * Re-creating a previously deleted identity with the same external ID * Migration or import processes that don't check for existing identities * Duplicate API calls due to retries or network issues Here's an example of a request that would trigger this error: ```bash # Attempting to create an identity with an external ID that already exists curl -X POST https://api.unkey.com/v2/identities.createIdentity \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "externalId": "user_123", "meta": { "name": "John Doe", "email": "john@example.com" } }' ``` ## How To Fix When you encounter this error, you have several options: 1. **Use a different external ID**: If creating a new identity, use a unique external ID 2. **Update the existing identity**: If you want to modify an existing identity, use the update endpoint instead 3. **Get the existing identity**: If you just need the identity information, retrieve it rather than creating it 4. **Implement upsert logic**: Use a get-or-create pattern in your code Here's how to update an existing identity: ```bash curl -X POST https://api.unkey.com/v1/identities.updateIdentity \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "externalId": "user_123", "meta": { "name": "John Doe", "email": "updated_email@example.com" } }' ``` Or implement a get-or-create pattern in your code: ```javascript // Pseudocode for get-or-create pattern async function getOrCreateIdentity(externalId, meta) { try { // Try to create the identity return await createIdentity(externalId, meta); } catch (error) { // If it already exists (409 error), get it instead if (error.status === 409) { return await getIdentity(externalId); } // Otherwise, rethrow the error throw error; } } ``` ## Common Mistakes * **Not checking for existing identities**: Failing to check if an identity already exists before creating it * **Retry loops**: Repeatedly trying to create the same identity after a failure * **Case sensitivity**: Not accounting for case sensitivity in external IDs * **Cross-environment duplication**: Using the same external IDs across development and production environments ## Related Errors * [err:unkey:data:identity\_not\_found](./identity_not_found) - When the requested identity doesn't exist * [err:unkey:authorization:insufficient\_permissions](../authorization/insufficient_permissions) - When you don't have permission to perform operations on identities # err:unkey:data:identity_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/identity_not_found The requested identity was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The requested identity could not be found", "status": 404, "title": "Not Found", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/identity_not_found" } } ``` ## What Happened? This error occurs when you're trying to perform an operation on an identity that doesn't exist in the Unkey system. Identities in Unkey are used to represent users or entities that own or use API keys. Common scenarios that trigger this error: * Using an incorrect identity ID or external ID * Referencing an identity that has been deleted * Trying to update or get information about a non-existent identity * Typos in identity identifiers Here's an example of a request that would trigger this error: ```bash # Attempting to get a non-existent identity curl -X POST https://api.unkey.com/v1/identities.getIdentity \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "identityId": "ident_nonexistent" }' ``` ## How To Fix Verify that you're using the correct identity ID or external ID and that the identity still exists in your workspace: 1. Check the identity ID in your request for typos or formatting errors 2. List all identities in your workspace to find the correct ID 3. If the identity has been deleted, you may need to recreate it Here's how to list identities in your workspace: ```bash curl -X GET https://api.unkey.com/v1/identities.listIdentities \ -H "Authorization: Bearer unkey_YOUR_API_KEY" ``` If you need to create a new identity, use the `identities.createIdentity` endpoint: ```bash curl -X POST https://api.unkey.com/v2/identities.createIdentity \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "externalId": "user_123", "meta": { "name": "John Doe", "email": "john@example.com" } }' ``` ## Common Mistakes * **Incorrect identifiers**: Using wrong identity IDs or external IDs * **Deleted identities**: Attempting to reference identities that have been removed * **Case sensitivity**: External IDs might be case-sensitive * **Workspace boundaries**: Trying to access identities from another workspace ## Related Errors * [err:unkey:data:identity\_already\_exists](./identity_already_exists) - When trying to create an identity that already exists * [err:unkey:data:key\_not\_found](./key_not_found) - When the requested key doesn't exist * [err:unkey:authorization:insufficient\_permissions](../authorization/insufficient_permissions) - When you don't have permission to perform operations on identities # err:unkey:data:key_auth_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/key_auth_not_found The requested key authentication was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The requested key authentication could not be found", "status": 404, "title": "Not Found", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/key_auth_not_found" } } ``` ## What Happened? This error occurs when you're trying to perform an operation on a key authentication record that doesn't exist in the Unkey system. Key authentication records contain information about how API keys are authenticated. Common scenarios that trigger this error: * Using an incorrect key authentication ID * Referencing a key authentication record that has been deleted * Attempting to update authentication settings for a non-existent record * Typos in identifiers Here's an example of a request that might trigger this error: ```bash # Attempting to update a non-existent key authentication record curl -X POST https://api.unkey.com/v1/keys.updateKeyAuth \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "keyAuthId": "kauth_nonexistent", "enabled": true }' ``` ## How To Fix Verify that you're using the correct key authentication ID and that the record still exists: 1. Check the key authentication ID in your request for typos or formatting errors 2. Verify the key authentication record exists by looking up the associated key 3. If the record has been deleted, you may need to recreate the key or its authentication settings Here's how to get information about a key's authentication settings: ```bash curl -X POST https://api.unkey.com/v1/keys.getKey \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "keyId": "key_your_key_id" }' ``` ## Common Mistakes * **Copy-paste errors**: Incorrect IDs due to copy-paste mistakes * **Deleted records**: Attempting to reference authentication records for deleted keys * **Misunderstanding relationships**: Confusing key IDs with key authentication IDs * **Workspace boundaries**: Trying to access authentication records from another workspace ## Related Errors * [err:unkey:data:key\_not\_found](./key_not_found) - When the requested key doesn't exist * [err:unkey:authentication:key\_not\_found](../authentication/key_not_found) - When an API key used for authentication doesn't exist * [err:unkey:authorization:key\_disabled](../authorization/key_disabled) - When the authentication key is disabled # err:unkey:data:key_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/key_not_found The requested key was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The requested API key could not be found", "status": 404, "title": "Not Found", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/key_not_found" } } ``` ## What Happened? This error occurs when you're trying to perform an operation on a specific API key using its ID, but the key with that ID doesn't exist in the system. This is different from the authentication error `err:unkey:authentication:key_not_found`, which occurs during the authentication process. Common scenarios that trigger this error: * Attempting to update, delete, or get information about a key that has been deleted * Using an incorrect or malformed key ID * Trying to access a key that exists in a different workspace * Reference to a key that hasn't been created yet Here's an example of a request that would trigger this error: ```bash # Attempting to get details for a non-existent key curl -X POST https://api.unkey.com/v1/keys.getKey \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "keyId": "key_nonexistent" }' ``` ## How To Fix Verify that you're using the correct key ID and that the key still exists in your workspace: 1. Check the key ID in your request for typos or formatting errors 2. Confirm the key exists by listing all keys in your workspace via the [Unkey dashboard](https://unkey.com/dashboard) or the API 3. Verify you're working in the correct workspace 4. If you need to create a new key, use the `keys.createKey` endpoint Here's how to list all keys to find the correct ID: ```bash curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "apiId": "api_your_api_id" }' ``` ## Common Mistakes * **Copy-paste errors**: Incorrect key IDs due to copy-paste mistakes * **Deleted keys**: Attempting to reference keys that have been deleted * **Environment confusion**: Looking for a key in production that only exists in development * **Workspace boundaries**: Trying to access a key that exists in another workspace ## Related Errors * [err:unkey:authentication:key\_not\_found](../authentication/key_not_found) - When an API key used for authentication doesn't exist * [err:unkey:data:api\_not\_found](./api_not_found) - When the requested API doesn't exist * [err:unkey:data:workspace\_not\_found](./workspace_not_found) - When the requested workspace doesn't exist # err:unkey:data:permission_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/permission_not_found The requested permission was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The requested permission could not be found", "status": 404, "title": "Not Found", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/permission_not_found" } } ``` ## What Happened? This error occurs when you're trying to perform an operation on a permission that doesn't exist in the Unkey system. Permissions in Unkey are used to control access to resources and operations. Common scenarios that trigger this error: * Using an incorrect permission ID or name * Referencing a permission that has been deleted * Trying to assign a permission that doesn't exist in the current workspace * Typos in permission names when using name-based lookups Here's an example of a request that would trigger this error: ```bash # Attempting to assign a non-existent permission to a role curl -X POST https://api.unkey.com/v1/roles.addPermission \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "roleId": "role_123abc", "permissionId": "perm_nonexistent" }' ``` ## How To Fix Verify that you're using the correct permission ID or name and that the permission still exists in your workspace: 1. List all permissions in your workspace to find the correct ID 2. Check if the permission has been deleted and recreate it if necessary 3. Verify you're working in the correct workspace Here's how to list all permissions in your workspace: ```bash curl -X GET https://api.unkey.com/v1/permissions.listPermissions \ -H "Authorization: Bearer unkey_YOUR_API_KEY" ``` If you need to create a new permission, use the appropriate API endpoint: ```bash curl -X POST https://api.unkey.com/v1/permissions.createPermission \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "name": "read:keys", "description": "Allows reading key information" }' ``` ## Common Mistakes * **Incorrect identifiers**: Using wrong permission IDs or names * **Deleted permissions**: Referencing permissions that have been removed * **Case sensitivity**: Permissions names might be case-sensitive * **Workspace boundaries**: Trying to use permissions from another workspace ## Related Errors * [err:unkey:data:role\_not\_found](./role_not_found) - When the requested role doesn't exist * [err:unkey:data:api\_not\_found](./api_not_found) - When the requested API doesn't exist * [err:unkey:authorization:insufficient\_permissions](../authorization/insufficient_permissions) - When you don't have permission to perform operations on permissions # err:unkey:data:ratelimit_namespace_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/ratelimit_namespace_not_found The requested rate limit namespace was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The requested rate limit namespace could not be found", "status": 404, "title": "Not Found", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/ratelimit_namespace_not_found" } } ``` ## What Happened? This error occurs when you're trying to perform an operation on a rate limit namespace that doesn't exist in the Unkey system. Rate limit namespaces are used to organize and manage rate limits for different resources or operations. Common scenarios that trigger this error: * Using an incorrect namespace ID or name * Referencing a namespace that has been deleted * Trying to modify a namespace that doesn't exist in the current workspace * Typos in namespace names when using name-based lookups Here's an example of a request that would trigger this error: ```bash # Attempting to get overrides for a non-existent namespace curl -X POST https://api.unkey.com/v2/ratelimit.listOverrides \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "namespaceName": "nonexistent_namespace" }' ``` ## How To Fix Verify that you're using the correct namespace ID or name and that the namespace still exists in your workspace: 1. Check the namespace ID or name in your request for typos or formatting errors 2. List all namespaces in your workspace to find the correct ID or name 3. If the namespace has been deleted, you may need to recreate it Here's how to use the correct namespace in a rate limit operation: ```bash # Creating a rate limit using a valid namespace curl -X POST https://api.unkey.com/v2/ratelimit.limit \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "namespace": "your_valid_namespace", "identifier": "user_123", "limit": 100, "duration": 60000 }' ``` ## Common Mistakes * **Typos in namespace names**: Small typographical errors in namespace names * **Case sensitivity**: Namespace names might be case-sensitive * **Deleted namespaces**: Referencing namespaces that have been removed * **Workspace boundaries**: Trying to use namespaces from another workspace ## Related Errors * [err:unkey:data:ratelimit\_override\_not\_found](./ratelimit_override_not_found) - When the requested rate limit override doesn't exist * [err:unkey:authorization:insufficient\_permissions](../authorization/insufficient_permissions) - When you don't have permission to perform operations on rate limits * [err:unkey:data:workspace\_not\_found](./workspace_not_found) - When the requested workspace doesn't exist # err:unkey:data:ratelimit_override_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/ratelimit_override_not_found The requested rate limit override was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The requested rate limit override could not be found", "status": 404, "title": "Not Found", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/ratelimit_override_not_found" } } ``` ## What Happened? This error occurs when you're trying to perform an operation on a rate limit override that doesn't exist in the Unkey system. Rate limit overrides are used to create custom rate limits for specific identifiers within a namespace. Common scenarios that trigger this error: * Using an incorrect override ID * Referencing an override that has been deleted * Trying to get or modify an override for an identifier that doesn't have one * Using the wrong namespace when looking up an override Here's an example of a request that would trigger this error: ```bash # Attempting to get a non-existent rate limit override curl -X POST https://api.unkey.com/v2/ratelimit.getOverride \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "namespaceId": "ns_123abc", "identifier": "user_without_override" }' ``` ## How To Fix Verify that you're using the correct namespace and identifier, and that the override still exists: 1. Check the namespace ID and identifier in your request for typos 2. List all overrides in the namespace to confirm if the one you're looking for exists 3. If the override has been deleted or never existed, you may need to create it Here's how to list overrides in a namespace: ```bash curl -X POST https://api.unkey.com/v2/ratelimit.listOverrides \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "namespaceId": "ns_123abc" }' ``` If you need to create a new override, use the `ratelimit.setOverride` endpoint: ```bash curl -X POST https://api.unkey.com/v2/ratelimit.setOverride \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "namespaceId": "ns_123abc", "identifier": "user_123", "limit": 200, "duration": 60000 }' ``` ## Common Mistakes * **Wrong identifier**: Using an incorrect user identifier when looking up overrides * **Deleted overrides**: Attempting to reference overrides that have been removed * **Namespace mismatch**: Looking in the wrong namespace for an override * **Assuming defaults are overrides**: Trying to get an override for an identifier that's using default limits ## Related Errors * [err:unkey:data:ratelimit\_namespace\_not\_found](./ratelimit_namespace_not_found) - When the requested rate limit namespace doesn't exist * [err:unkey:authorization:insufficient\_permissions](../authorization/insufficient_permissions) - When you don't have permission to perform operations on rate limit overrides * [err:unkey:data:workspace\_not\_found](./workspace_not_found) - When the requested workspace doesn't exist # err:unkey:data:role_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/role_not_found The requested role was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The requested role could not be found", "status": 404, "title": "Not Found", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/role_not_found" } } ``` ## What Happened? This error occurs when you're trying to perform an operation on a role that doesn't exist in the Unkey system. Roles in Unkey are collections of permissions that can be assigned to users or API keys. Common scenarios that trigger this error: * Using an incorrect role ID or name * Referencing a role that has been deleted * Trying to assign a role that doesn't exist in the current workspace * Typos in role names when using name-based lookups Here's an example of a request that would trigger this error: ```bash # Attempting to add a permission to a non-existent role curl -X POST https://api.unkey.com/v1/roles.addPermission \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "roleId": "role_nonexistent", "permissionId": "perm_123abc" }' ``` ## How To Fix Verify that you're using the correct role ID or name and that the role still exists in your workspace: 1. List all roles in your workspace to find the correct ID 2. Check if the role has been deleted and recreate it if necessary 3. Verify you're working in the correct workspace Here's how to list all roles in your workspace: ```bash curl -X GET https://api.unkey.com/v1/roles.listRoles \ -H "Authorization: Bearer unkey_YOUR_API_KEY" ``` If you need to create a new role, use the appropriate API endpoint: ```bash curl -X POST https://api.unkey.com/v1/roles.createRole \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "name": "API Reader", "description": "Can read API information" }' ``` ## Common Mistakes * **Incorrect identifiers**: Using wrong role IDs or names * **Deleted roles**: Referencing roles that have been removed * **Case sensitivity**: Role names might be case-sensitive * **Workspace boundaries**: Trying to use roles from another workspace ## Related Errors * [err:unkey:data:permission\_not\_found](./permission_not_found) - When the requested permission doesn't exist * [err:unkey:data:api\_not\_found](./api_not_found) - When the requested API doesn't exist * [err:unkey:authorization:insufficient\_permissions](../authorization/insufficient_permissions) - When you don't have permission to perform operations on roles # err:unkey:data:workspace_not_found Source: https://unkey.com/docs/api-reference/errors-v2/unkey/data/workspace_not_found The requested workspace was not found ```json Example { "meta": { "requestId": "req_2c9a0jf23l4k567" }, "error": { "detail": "The requested workspace could not be found", "status": 404, "title": "Not Found", "type": "https://unkey.com/docs/api-reference/errors-v2/unkey/data/workspace_not_found" } } ``` ## What Happened? This error occurs when you're trying to perform an operation on a workspace that doesn't exist in the Unkey system. This can happen when referencing a workspace by ID or name in API calls. Common scenarios that trigger this error: * Using an incorrect workspace ID * Referencing a workspace that has been deleted * Attempting to access a workspace you don't have permission to see * Typos in workspace names when using name-based lookups Here's an example of a request that would trigger this error: ```bash # Attempting to list keys in a non-existent workspace curl -X POST https://api.unkey.com/v1/keys.listKeys \ -H "Content-Type: application/json" \ -H "Authorization: Bearer unkey_YOUR_API_KEY" \ -d '{ "workspaceId": "ws_nonexistent" }' ``` ## How To Fix Verify that you're using the correct workspace ID or name and that the workspace still exists: 1. Check your Unkey dashboard to see a list of workspaces you have access to 2. Verify the workspace ID or name in your API calls 3. Ensure you have permission to access the workspace 4. If needed, create a new workspace through the dashboard or API To find your correct workspace ID, you can: ```bash # List workspaces you have access to curl -X GET https://api.unkey.com/v1/workspaces.listWorkspaces \ -H "Authorization: Bearer unkey_YOUR_API_KEY" ``` ## Common Mistakes * **Deleted workspaces**: Attempting to reference workspaces that have been deleted * **Copy-paste errors**: Using incorrect IDs from documentation examples * **Permission issues**: Trying to access workspaces you've been removed from * **Case sensitivity**: Using incorrect casing in workspace name lookups ## Related Errors * [err:unkey:authorization:workspace\_disabled](../authorization/workspace_disabled) - When the workspace exists but is disabled * [err:unkey:data:api\_not\_found](./api_not_found) - When the requested API doesn't exist * [err:unkey:data:key\_not\_found](./key_not_found) - When the requested key doesn't exist # INSUFFICIENT_PERMISSIONS Source: https://unkey.com/docs/api-reference/errors/code/BAD_REQUEST ## Problem You do not have permission to perform this action. In most cases this means the root key you are using, is lacking permissions. ## Solution Go to the [Unkey Dashboard](https://app.unkey.com/settings/root-keys) and add the required permissions to your key. # CONFLICT Source: https://unkey.com/docs/api-reference/errors/code/CONFLICT ## Problem Another resource already uses this identifier. For example workspace slugs must be unique globally. ## Solution Please choose a different name/identifier. If that doesn't help, ask for help on [Discord](https://unkey.com/discord) # DELETE_PROTECTED Source: https://unkey.com/docs/api-reference/errors/code/DELETE_PROTECTED ## Problem The resource you are trying to delete is protected and cannot be deleted. ## Solution Go to the [Unkey Dashboard](https://app.unkey.com) and remove the protection from the resource you are trying to delete. # DISABLED Source: https://unkey.com/docs/api-reference/errors/code/DISABLED ## Problem The key has been disabled. ## Solution Enable this key using the [updateKey endpoint](/api-reference/keys/update) or web interface. If that doesn't help, ask for help on [Discord](https://unkey.com/discord) # EXPIRED Source: https://unkey.com/docs/api-reference/errors/code/EXPIRED ## Problem The key has expired and can no longer be used. ## Solution Check the `expires` field and update the key if necessary. If that doesn't help, ask for help on [Discord](https://unkey.com/discord) # FORBIDDEN Source: https://unkey.com/docs/api-reference/errors/code/FORBIDDEN ## Problem We were able to authenticate you but you do not have access to the requested resources. ## Solution Use the correct key and/or double check you are requesting the correct resources. If that doesn't help, ask for help on [Discord](https://unkey.com/discord) # INSUFFICIENT_PERMISSIONS Source: https://unkey.com/docs/api-reference/errors/code/INSUFFICIENT_PERMISSIONS ## Problem You do not have permission to perform this action. In most cases this means the root key you are using, is lacking permissions. ## Solution Go to the [Unkey Dashboard](https://app.unkey.com/settings/root-keys) and add the required permissions to your key. # INTERNAL_SERVER_ERROR Source: https://unkey.com/docs/api-reference/errors/code/INTERNAL_SERVER_ERROR ## Problem Something unexpected happened and we did not handle the error well. ## Solution Please get in touch on [Discord](https://unkey.com/discord) and provide the full error response. # NOT_FOUND Source: https://unkey.com/docs/api-reference/errors/code/NOT_FOUND ## Problem The requested resource could not be found. It may have been deleted or does not exist. ## Solution Please ensure that you are providing the correct resource identifier or check if the resource has been deleted. If that doesn't help, ask for help on [Discord](https://unkey.com/discord) # TOO_MANY_REQUESTS Source: https://unkey.com/docs/api-reference/errors/code/TOO_MANY_REQUESTS ## Problem You have made too many requests in a short period of time. ## Solution Please wait a bit and try again or increase the ratelimit on your API key. If that doesn't help, ask for help on [Discord](https://unkey.com/discord) # UNAUTHORIZED Source: https://unkey.com/docs/api-reference/errors/code/UNAUTHORIZED ## Problem We were unable to authorize your request. Either your key was missing, malformed or does not have the required permissions. ## Solution Check the `message` field and double check you are sending the key correctly in the `Authorization` header. If that doesn't help, ask for help on [Discord](https://unkey.com/discord) # Introduction Source: https://unkey.com/docs/api-reference/errors/introduction Machine and human readable error codes The Unkey API returns machine readable error codes to quickly identify the type of error as well as link to the docs and a `requestId`. Please always include the `requestId` in your error report. ```json { error: { code: "UNAUTHORIZED", message: "We were unable to authorize your request. Either your key was missing, malformed or does not have the required permissions.", docs: "https://unkey.api/docs/api-reference/errors/code/BAD_REQUEST", requestId: "req_1234567890" } } ``` If you can't debug something on your own or think there is a bug, please get in touch with us on [Discord](https://unkey.com/discord) or [Email](mailto:support@unkey.dev) and provide the full error response. # Create an identity Source: https://unkey.com/docs/api-reference/identities/create-identity post /v1/identities.createIdentity Identities are in public beta. Please report any issues to [support@unkey.dev](mailto:support@unkey.dev) Create a new identity in the system. This might not be necessary as newly created keys automatically create an identity if required. Identities map your users, organisations or other entities to keys. They can be used to share metadata and limits. [Read more about identities](/concepts/identities/overview) ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 17 2024 | Introduced endpoint | # Delete an identity Source: https://unkey.com/docs/api-reference/identities/delete-identity post /v1/identities.deleteIdentity Identities are in public beta. Please report any issues to [support@unkey.dev](mailto:support@unkey.dev) Delete an identity. This will not revoke the keys associated with the identity. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 17 2024 | Introduced endpoint | # Get an identity Source: https://unkey.com/docs/api-reference/identities/get-identity get /v1/identities.getIdentity Identities are in public beta. Please report any issues to [support@unkey.dev](mailto:support@unkey.dev) Retrieve an identity either by `identityId` or by `externalId`. The response will include the identity as well as its configured rate limits. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 17 2024 | Introduced endpoint | # List identities Source: https://unkey.com/docs/api-reference/identities/list-identities get /v1/identities.listIdentities Identities are in public beta. Please report any issues to [support@unkey.dev](mailto:support@unkey.dev) List all identities in the system. This will return a paginated list of identities. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 17 2024 | Introduced endpoint | # Update an identity Source: https://unkey.com/docs/api-reference/identities/update-identity post /v1/identities.updateIdentity Identities are in public beta. Please report any issues to [support@unkey.dev](mailto:support@unkey.dev) Update an identity's metadata or limits. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 17 2024 | Introduced endpoint | # Add Permissions Source: https://unkey.com/docs/api-reference/keys/add-permissions post /v1/keys.addPermissions Add one or more permissions to a key. Adds permissions to a key. Existing permissions are not removed. To use this endpoint, your root key must have the `rbac.*.add_permission_to_key` and potentially the `rbac.*.create_permission` permissions. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Add Roles Source: https://unkey.com/docs/api-reference/keys/add-roles post /v1/keys.addRoles Add one or more roles to a key. Adds roles to a key. Existing roles are not removed. To use this endpoint, your root key must have the `rbac.*.add_role_to_key` and potentially the `rbac.*.create_role` permissions. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Create a key Source: https://unkey.com/docs/api-reference/keys/create post /v1/keys.createKey Create a new key. ## Changelog | Date | Changes | | ----------- | ------------------- | | Dec 06 2023 | Introduced endpoint | # Delete a key Source: https://unkey.com/docs/api-reference/keys/delete post /v1/keys.deleteKey Deleted keys are no longer valid and will not be able to be used to authenticate requests. ## Changelog | Date | Changes | | ----------- | ------------------- | | Dec 06 2023 | Introduced endpoint | # Retrieve a key by ID Source: https://unkey.com/docs/api-reference/keys/get get /v1/keys.getKey ## Changelog | Date | Changes | | ----------- | -------------------------- | | Dec 06 2023 | Introduced endpoint | | May 15 2024 | Return updatedAt timestamp | | Aug 01 2024 | Return identities | # Remove Permissions Source: https://unkey.com/docs/api-reference/keys/remove-permissions post /v1/keys.removePermissions Remove one or more permissions from a key. To use this endpoint, your root key must have the `rbac.*.remove_permission_from_key` permission. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Remove Roles Source: https://unkey.com/docs/api-reference/keys/remove-roles post /v1/keys.removeRoles Remove one or more roles from a key. To use this endpoint, your root key must have the `rbac.*.remove_role_from_key` permission. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Set Permissions Source: https://unkey.com/docs/api-reference/keys/set-permissions post /v1/keys.setPermissions Overwrite the permissions of a key with a new set of permissions. Sets the permissions of a key to a new set of permissions. This endpoint overwrites the existing permissions of the key with the new set. Existing permissions that are not included in the new set are removed. You can provide either permission ids or permission names in the request body. If you provide a name, we will create the permission if it does not exist. To use this endpoint, your root key must have the `rbac.*.add_permission_to_key` and potentially the `rbac.*.create_permission` permissions. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Set Roles Source: https://unkey.com/docs/api-reference/keys/set-roles post /v1/keys.setRoles Overwrite the roles of a key with a new set of roles. Sets the roles of a key to a new set of roles. This endpoint overwrites the existing roles of the key with the new set. Existing roles that are not included in the new set are removed. You can provide either role ids or role names in the request body. If you provide a name, we will create the role if it does not exist. To use this endpoint, your root key must have the `rbac.*.add_role_to_key` and potentially the `rbac.*.create_role` permissions. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Update a key Source: https://unkey.com/docs/api-reference/keys/update post /v1/keys.updateKey Updates the configuration of an existing key. Omit fields to leave unchanged. ## Changelog | Date | Changes | | ----------- | ------------------- | | Dec 06 2023 | Introduced endpoint | # Update a key's remaining limit Source: https://unkey.com/docs/api-reference/keys/update-remaining post /v1/keys.updateRemaining ## Changelog | Date | Changes | | ----------- | ------------------- | | Dec 06 2023 | Introduced endpoint | # Verify a key Source: https://unkey.com/docs/api-reference/keys/verify post /v1/keys.verifyKey ## Changelog | Date | Changes | | ----------- | -------------------- | | Dec 06 2023 | Introduced endpoint | | Jul 08 2024 | Added `EXPIRED` code | # Returns data about a key Source: https://unkey.com/docs/api-reference/keys/whoami post /v1/keys.whoami ## Changelog | Date | Changes | | ----------- | ------------------- | | Oct 07 2024 | Introduced endpoint | You may not always have easy access to the `keyId` and therefore can't use [`/v1/keys.getKey`](/api-reference/keys/get). This offers an escape hatch to send us the real key instead. # Migrate key to Unkey Source: https://unkey.com/docs/api-reference/migrations/create-keys post /v1/migrations.createKeys Add existing keys to unkey by specifying the key hash and other settings. This endpoint supports bulk inserts of up to 100 keys at a time. If you have more keys, you can call this endpoint multiple times. If any operation fails (e.g., due to a duplicate key), everything will be rolled back and no keys are created. ## Changelog | Date | Changes | | ----------- | ------------------- | | May 08 2024 | Introduced endpoint | # Overview Source: https://unkey.com/docs/api-reference/overview General information about the API. The Unkey API uses HTTP RPC-style methods and generally follow the schema: ``` https://api.unkey.dev/{version}/{service}.{method} ``` For example `GET https://api.unkey.dev/v1/apis.listKeys` to list all keys for an API. ## HTTP Methods We strictly use only `GET` and `POST` methods. `PUT` and `DELETE` are not used. ### `GET` `GET` methods are used for reading data. Filtering, sorting, or pagination is done via query parameters. ```http curl "https://api.unkey.dev/v1/keys.getKey?keyId=key_123" \ -H "Authorization: Bearer " ``` ### `POST` `POST` methods are used for creating, updating, and deleting data. Data is passed as `application/json` in the request body. ```http curl -XPOST "https://api.unkey.dev/v1/keys.createKey" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"apiId": "api_123", "name": "My Key"}' ``` # Create A Permission Source: https://unkey.com/docs/api-reference/permissions/create-permission post /v1/permissions.createPermission To use this endpoint, your root key must have the `rbac.*.create_permission` permission. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Create A Role Source: https://unkey.com/docs/api-reference/permissions/create-role post /v1/permissions.createRole To use this endpoint, your root key must have the `rbac.*.create_role` permission. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Delete A Permission Source: https://unkey.com/docs/api-reference/permissions/delete-permission post /v1/permissions.deletePermission To use this endpoint, your root key must have the `rbac.*.delete_permission` permission. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Delete A Role Source: https://unkey.com/docs/api-reference/permissions/delete-role post /v1/permissions.deleteRole To use this endpoint, your root key must have the `rbac.*.delete_role` permission. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Get Permission Source: https://unkey.com/docs/api-reference/permissions/get-permission get /v1/permissions.getPermission To use this endpoint, your root key must have the `rbac.*.read_permission` permission. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Get Role Source: https://unkey.com/docs/api-reference/permissions/get-role get /v1/permissions.getRole To use this endpoint, your root key must have the `rbac.*.read_role` permission. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # List Permissions Source: https://unkey.com/docs/api-reference/permissions/list-permissions get /v1/permissions.listPermissions To use this endpoint, your root key must have the `rbac.*.read_permission` permission. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # List Roles Source: https://unkey.com/docs/api-reference/permissions/list-roles get /v1/permissions.listRoles To use this endpoint, your root key must have the `rbac.*.read_role` permission. ## Changelog | Date | Changes | | ----------- | ------------------- | | Jul 08 2024 | Introduced endpoint | # Delete Override Source: https://unkey.com/docs/api-reference/ratelimits/delete-override post /v1/ratelimits.deleteOverride Delete an override from the system. ## Changelog | Date | Changes | | ----------- | ------------------- | | Nov 25 2024 | Introduced endpoint | # Get Override Source: https://unkey.com/docs/api-reference/ratelimits/get-override get /v1/ratelimits.getOverride Retrieve the configured override by `namespaceId` or `namespaceName`. ## Changelog | Date | Changes | | ----------- | ------------------- | | Nov 25 2024 | Introduced endpoint | # Ratelimit Source: https://unkey.com/docs/api-reference/ratelimits/limit post /v1/ratelimits.limit Ratelimit an action based on an identifier. ## Changelog | Date | Changes | | ----------- | ------------------- | | Mar 16 2024 | Introduced endpoint | # List Overrides Source: https://unkey.com/docs/api-reference/ratelimits/list-overrides get /v1/ratelimits.listOverrides Retrieve a list of configured overrides by `namespaceId` or `namespaceName`. ## Changelog | Date | Changes | | ----------- | ------------------- | | Nov 25 2024 | Introduced endpoint | # Set Override Source: https://unkey.com/docs/api-reference/ratelimits/set-override post /v1/ratelimits.setOverride Create or update an override to set specific limits for an identifier. There is no `update` endpoint. Instead you should call this endpoint again to overwrite your override. ## Changelog | Date | Changes | | ----------- | ------------------- | | Nov 25 2024 | Introduced endpoint | # Analytics Source: https://unkey.com/docs/apis/features/analytics Per key and per API analytics Unkey offers both per key and per API analytics that allow you to drive business decisions. ## Per API Analytics Our per API analytics offer a broad overview of the usage for a specific API with total keys, active keys and verifications in the last 30 days. Per API Analytics ## Per Key Analytics Our per key analytics give you a deep dive into each individual key, giving usage data, key data and where the requests originated from. This data can be useful for finding your top users, and where verifications are coming from. Per key analytics ## Tags You can add tags to verification requests to aggregate or filter data when querying. For example you might want to add the path of your API as a tag: `path=/v1/my-path` and then later retrieve a breakdown of api key usage per unique path. Unkey does not parse tags in any special way. The only limitations are: * Tags are strings. * You can specify up to 10 tags per request. * Each tag must be between (including) 1 and 128 characters. That being said, having some structure for your tags could be benefitial for you. A common theme is treating them as key-value pairs and specifying them with either a colon or equal-sign as delimiter. ``` key:value key=value ``` Since Unkey does not know what API routes your user has called or which resources they interact with, we encourage you to record these in the tags. Here's an example tags for a fictional blog API: ```json [ "path=/v1/posts.createPost", "postId=post_1asofijqknslkfqWF", "region=us-east-1", "apiVersion=f8ad21bd", // a git sha of your deployment or semver ] ``` ### Using tags Tags can be added in the request body. ```bash Providing Tags {7-10} curl --request POST \ --url https://api.unkey.dev/v1/keys.verifyKey \ --header 'Content-Type: application/json' \ --data '{ "apiId": "api_1234", "key": "sk_1234", "tags": [ "tag1", "path=/v1/my-resource/123" ] }' ``` ### Querying tags We have only rolled out tag ingestion so far to allow you to start recording data as early as possible. We're working on new query capabilities including filtering and aggregating by tags. # Example Source: https://unkey.com/docs/apis/features/authorization/example RBAC in the almost-real world Let's look at an example app for allowing your users to manage domains. As part of the API, your users will be able to perform CRUD operations against domains or individual dns records. Users of our app can have the following permissions: * `domain.delete_domain` * `domain.dns.create_record` * `domain.dns.read_record` * `domain.dns.update_record` * `domain.dns.delete_record` * `domain.create_domain` * `domain.read_domain` * `domain.update_domain` Create them in your [dashboard](https://app.unkey.com/authorization/permissions). Example permissions And we define the following roles: * `admin`: An admin can do everything * `dns.manager`: Can create, read, update and delete dns records but not access the domain itself * `read-only`: Can read domain or dns record information. Example roles Create them in your [dashboard](https://app.unkey.com/authorization/roles) too. For each role, we need to connect the permissions it should have. Go to [/app/authorization/roles](https://app.unkey.com/authorization/roles) and click on the role to go to the permissions screen. Admin roles dns.manager roles read-only roles Now that we have permissions and roles in place, we can connect them to keys. 1. In the sidebar, click on one of your APIs 2. In the breakcrumb navigation on the top click Reqests and then keys Breadcrumb Navigation 3. Select one of your existing keys by clicking on it 4. Scroll down to the `Roles` section if not visible You should now be on `/app/keys/key_auth_???/key_???` Unconnected roles and permissions You can connect a role to your key by clicking on the checkbox. Let's give this key the `dns.manager` and `read-only` roles. A toast message should come up in the lower corner when the action has been completed. Unconnected roles and permissions As you can see, now the key now contains 2 `roles` and 5 `permissions` shown just above the Roles section: You can attach roles to a key when creating it by providing the role names as an array: ```bash curl -XPOST \ --url https://api.unkey.dev/v1/keys.createKey \ -H "Authorization: Bearer ${ROOT_KEY}" \ -H "Content-Type: application/json" \ -d '{ "apiId": "${API_ID}", "roles": [ "role1", "role2", "role3" ] }' ``` See [here](/api-reference/keys/create) for details. Now you can verify this key and perform permission checks. [Read more](/apis/features/authorization/verifying) # Overview Source: https://unkey.com/docs/apis/features/authorization/introduction Access Control with Roles and Permissions Role-Based Access Control (RBAC) is a security paradigm that restricts system access to authorized actors. It is based on the principle of assigning roles to actors and defining what actions or resources each role can access. We are taking this one step further and allowing you to attach arbitrary permissions to keys, for more flexibility (Coming in Q2). # Roles and Permissions Source: https://unkey.com/docs/apis/features/authorization/roles-and-permissions In RBAC, roles represent a collection of permissions. Each role defines a set of actions or operations that a user with that role can perform. Permissions can be associated with various resources within your application, such as endpoints, data objects, or functionality. Common roles may include: * `Administrator`: Has full access to all resources and functionality. * `Editor`: Can create, read, update, and delete specific resources. * `Viewer`: Can only view resources but cannot modify them. ## Roles Creating, updating and deleting roles is available in the dashboard. ### Create 1. Go to [/app/authorization/roles](https://app.unkey.com/authorization/roles) 2. Click `Create New Role` 3. Enter a unique name for your role and optionally a human readable description. 4. Click `Create` After the role is created, you are forwarded and can update/delete the role or connect existing permissions. ### Update 1. Go to [/app/authorization/roles](https://app.unkey.com/authorization/roles) 2. Click on the role you want to update 3. Click `Update Role` 4. Make changes to the name, description or both 5. Click `Save` ### Delete 1. Go to [/app/authorization/roles](https://app.unkey.com/authorization/roles) 2. Click on the role you want to delete 3. Click `Delete Role` 4. Enter the name of the role to confirm 5. Click `Delete Role` ## Permissions Creating, updating and deleting permissions is available in the dashboard. ### Create 1. Go to [/app/authorization/permissions](https://app.unkey.com/authorization/permissions) 2. Click `Create New Permission` 3. Enter a unique name for your permissoin and optionally a human readable description. 4. Click `Create New Permission` ### Update 1. Go to [/app/authorization/permissions](https://app.unkey.com/authorization/permissions) 2. Click on the permission you want to update 3. Click `Update Role` 4. Make changes to the name, description or both 5. Click `Save` ### Delete 1. Go to [/app/authorization/permisions](https://app.unkey.com/authorization/permisions) 2. Click on the permission you want to delete 3. Click `Delete` 4. Enter the name of the permission to confirm 5. Click `Delete` ## Connecting roles and permissions After you have created at least 1 role and 1 permission, you can start associating them with each other. Go to [/app/authorization/roles](https://app.unkey.com/authorization/roles) and click on the role to go to the permissions screen. Now you can click the checkboxes to connect the role and permission. A checked box means the role will grant the permission to keys. Read-only roles ## Connecting roles to keys 1. In the sidebar, click on one of your APIs 2. In the breakcrumb navigation on the top click Reqests and then keys Breadcrumb Navigation 3. Select one of your existing keys by clicking on it 4. Scroll down to the `Roles` section if not visible You should now be on `/app/keys/key_auth_???/key_???` Unconnected roles and permissions You can connect a role to your key by clicking on the checkbox. Let's give this key the `dns.manager` and `read-only` roles. A toast message should come up in the lower corner when the action has been completed. Unconnected roles and permissions As you can see, now the key now contains 2 `roles` and 5 `permissions` shown just above the Roles section: ## Creating keys When a user of your app creates a new key, you can attach zero, one or multiple previously created roles to the key. ```bash curl -XPOST \ --url https://api.unkey.dev/v1/keys.createKey \ -H "Authorization: Bearer ${ROOT_KEY}" \ -H "Content-Type: application/json" \ -d '{ "apiId": "${API_ID}", "roles": [ "role1", "role2", "role3" ] }' ``` See [here](/api-reference/keys/create) for details. # Verifying Source: https://unkey.com/docs/apis/features/authorization/verifying Verifying permissions through the API Once a key is generated, you can verify it using the [verify](/api-reference/keys/verify) endpoint. Our system verifies whether the key has the necessary permissions to perform the requested action(s). If the user's role grants the required permissions, the request is allowed to proceed; otherwise, access is denied. This will return valid if the key has the permission: `admin` ```bash Single Permission curl --request POST \ --url https://api.unkey.dev/v1/keys.verifyKey \ --header 'Content-Type: application/json' \ --data '{ "apiId": "api_1234", "key": "sk_1234", "authorization": { "permissions": "admin" } }' ``` This will return valid if the key has either `admin` or both `dns.record.read` and `dns.record.update` permissions. ```bash Nested Query curl --request POST \ --url https://api.unkey.dev/v1/keys.verifyKey \ --header 'Content-Type: application/json' \ --data '{ "apiId": "api_1234", "key": "sk_1234", "authorization": { "permissions": { "or": [ "admin", { "and": [ "dns.record.read", "dns.record.update" ] } ] } } }' ``` Sometimes you just don't know what permissions are required before loading resources from your database. In these cases you can manually check permissions as well. Verify the key and all permissions that you already know before needing to query your database. If the response is invalid, you can return early. The key is at least valid, so you can query our database to fetch more information. The verification response from step 1 includes all permissions attached to the keys and looks something like this: ```json { valid: true, permissions: ["permission1", "permission2", ...] //... omited for brevity } ``` Use the attached permissions and the context loaded from your database to determine if you should proceed handling the request or returning an authorization error. # Disabling Keys Source: https://unkey.com/docs/apis/features/enabled Enable or disable a key. Disabled keys will not validate. This feature is useful for disabling a key temporarily. While disabled the key will act as an invalid key. Example: Suppose you have a customer that has not paid their bill. You may not want to delete the key and wait for the account balance to be current. The key can be disabled temporarily, preventing access until it is enabled. Unkey allows you to disable a key on an individual basis. ### Example Let's disable a key temperarily blocking access with that key. ```bash curl --request POST \ --url https://api.unkey.dev/v1/keys.updateKey \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "enabled": false, "keyId": "" }' ``` Now, when you verify the updated key it will show as invalid. ```bash curl --request POST \ --url https://api.unkey.dev/v1/keys.verifyKey \ --header 'Content-Type: application/json' \ --data '{ "key": "" }' ``` ```json { "keyId": "", "valid": false, "meta": {}, "enabled": false } ``` The returned `enabled` value can be changed with the updateKey endpoint to re-enable the key. # Environments Source: https://unkey.com/docs/apis/features/environments Separate your keys into live and test environments. For many applications it's useful to provide keys for developing and testing to your users. They can not interact with real production resources and may have lower ratelimits but use the exact same flow as your `live` keys. Unkey allows you to set an arbitrary value as `environment` for each key, so you can model your domain however you want. In practice we often see two distinct environments being used a lot: * `live` Live keys are used in production and affect real resources. * `test` Test keys allow you to develop and test your code without modifying real resources. It's great to ensure your code is working manually or can be used in automated tests. You may also want to associate different ratelimits per environment or bill usage differently. Perhaps test keys have lower limits but are free to use. ### Creating a key with an environment Using the prefix to indicate the environment is optional but highly recommended. It can prevent your user from accidentally using keys interchangably and modifying resources unintentionally. ```bash Test curl --request POST \ --url https://api.unkey.dev/v1/keys.createKey \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "environment": "test", "prefix": "sk_test" }' ``` ```bash Live curl --request POST \ --url https://api.unkey.dev/v1/keys.createKey \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "environment": "live", "prefix": "sk_live" }' ``` For more details, see the [API reference](/api-reference/keys/create) ### Verifying a key When you are using different environments, you obviously need a way to know what environment the used key is in. We provide this as part of the verification response: ```bash curl --request POST \ --url https://api.unkey.dev/v1/keys.verifyKey \ --header 'Content-Type: application/json' \ --data '{ "apiId": "api_1234", "key": "sk_1234" }' ``` The response would look something like this: ```json { "valid": true, "environment": "test", // ... omited } ``` # Modes Source: https://unkey.com/docs/apis/features/ratelimiting/modes Latency or consistency? Choose the right mode for your usecase. Unkey offers `fixed window` rate limiting out of the box for all API keys. This means that you can set a limit on how many requests a key can make in a given time window. If the limit is exceeded, the key will be blocked from making further requests until the window resets. We provide 2 ways of rate limiting, optimized for different usecases. ## Local, fast rate limiting at the edge API key validation is very sensitive to latency because it is in the critical path of your application. Therefore minimizing the latency impact of rate limiting is a key priority. Rate limiting at the edge comes with no latency increase and effectively rate limits your users at each edge location. To make this possible, each edge location maintains their own rate limiting and updates with the global state asynchronously, thus a user could exceed your rate limit if they go through different edge locations. This way of limiting is effective to protect your application because there is a guaranteed upper bound after all edge locations the user is accessing have reached their limit. ### Example ```bash curl --request POST \ --url https://api.unkey.dev/v1/keys.createKey \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "apiId":"", "prefix":"xyz", "byteLength":16, "ownerId":"", "ratelimit":{ "async": true, // edge rate limiting "limit": 10, "duration": 1000 } }' ``` ## Global consensus rate limiting If having a strict rate limit that must not be exceeded, even when verifying keys in multiple regions, is required, then this is a good option. This way of limiting is guaranteed to be consistent globally, but it comes with a higher latency impact. Typically most of your traffic should pass, and we recommend using the local rate limiting to provide a better user experience and only use global rate limiting when you really need to. ### Example ```bash curl --request POST \ --url https://api.unkey.dev/v1/keys.createKey \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "apiId":"", "prefix":"xyz", "byteLength":16, "ownerId":"", "ratelimit":{ "async": false, // origin rate limiting "limit":10, "duration": 1000 } }' ``` # Overview Source: https://unkey.com/docs/apis/features/ratelimiting/overview How rate limiting works in unkey Unkey's ratelimiting system controls the number of requests a key can make within a given timeframe. This prevents abuse, protects your API from being overwhelmed, and enables usage-based billing models. ## Multi-Ratelimit System Unkey supports multiple named ratelimits per key, providing fine-grained control over different aspects of your API usage. You can define separate limits for different operations, time windows, and use cases within a single key. The system offers two types of ratelimits: auto-apply ratelimits that check automatically during verification, and manual ratelimits that require explicit specification in requests. ## Auto-Apply vs Manual Ratelimits Auto-apply ratelimits (`autoApply: true`) are checked automatically during every key verification without needing explicit specification. These work well for general usage limits that should always be enforced. ```bash # Create a key with auto-apply ratelimit curl -X POST https://api.unkey.dev/v1/keys.createKey \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "apiId": "api_123", "ratelimits": [ { "name": "general-requests", "limit": 100, "duration": 60000, "autoApply": true } ] }' ``` ```bash # Verify key - auto-apply ratelimits are checked automatically curl -X POST https://api.unkey.dev/v1/keys.verifyKey \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "apiId": "api_123", "key": "your_api_key_here" }' ``` Manual ratelimits (`autoApply: false`) must be explicitly specified in verification requests. Use these for operation-specific limits that only apply to certain endpoints. ```bash # Create a key with manual ratelimit curl -X POST https://api.unkey.dev/v1/keys.createKey \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "apiId": "api_123", "ratelimits": [ { "name": "expensive-operations" } ] }' ``` ```bash # Verify key - override cost explicitly curl -X POST https://api.unkey.dev/v1/keys.verifyKey \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "apiId": "api_123", "key": "your_api_key_here", "ratelimits": [ { "name": "expensive-operations", "cost": 2 } ] }' ``` ## Configuration Configure ratelimits on a per-key or per-identity basis through the dashboard or API. Each ratelimit requires a unique name, limit count, and duration in milliseconds. ```bash curl -X POST https://api.unkey.dev/v1/keys.createKey \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "apiId": "api_123", "ratelimits": [ { "name": "requests", "limit": 100, "duration": 60000, "autoApply": true }, { "name": "daily-quota", "limit": 1000, "duration": 86400000, "autoApply": true } ] }' ``` You can apply different costs to operations by specifying a cost parameter during verification. This allows resource-intensive operations to consume more of the rate limit than simple operations. ## Migration from Legacy System The legacy `ratelimit` field is deprecated. Use the `ratelimits` array instead. Existing keys with the legacy `ratelimit` field are automatically migrated to use a special "default" ratelimit with `autoApply: true`. This maintains backward compatibility without requiring code changes. The legacy format converts automatically: ```bash # Legacy format (deprecated) curl -X POST https://api.unkey.dev/v1/keys.createKey \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "apiId": "api_123", "ratelimit": { "limit": 100, "duration": 60000 } }' # Automatically becomes curl -X POST https://api.unkey.dev/v1/keys.createKey \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "apiId": "api_123", "ratelimits": [ { "name": "default", "limit": 100, "duration": 60000, "autoApply": true } ] }' ``` Remove the automatically migrated "default" ratelimit through the key settings in the dashboard or via the updateKey API endpoint if you no longer need it. ## Identity-Level Ratelimits Configure ratelimits at the identity level to share limits across multiple keys. Identity ratelimits work alongside key-level ratelimits, with key-level settings taking precedence for naming conflicts. ```bash curl -X POST https://api.unkey.dev/v1/identities.createIdentity \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "externalId": "user_123", "ratelimits": [ { "name": "user-requests", "limit": 1000, "duration": 3600000 } ] }' ``` This approach works well for user-based quotas where multiple API keys should share the same usage limits. # Refill Source: https://unkey.com/docs/apis/features/refill Refill remaining key verifications on a set interval This feature is useful for creating an API key that automatically refills daily or monthly. Daily refills trigger each night at midnight, while monthly refills are triggered on the first day of each month. Example: Suppose you are selling API access, and a customer has purchased 1000 API uses per month. On the first day of the month, the 1000 uses will be refilled for that key. Unkey allows you to set a refill interval and increment on individual keys, and we take care of refilling a key on its set interval. ### Example Let's create a new key that can be used 100 times a day. ```bash curl --request POST \ --url https://api.unkey.dev/v1/keys.createKey \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "apiId":"", "remaining": 100, "refill": { "interval": "daily", "amount": 100 } }' ``` Now, when you verify the new key, you will receive the remaining verifications. After all of them are used up, the key becomes invalid. ```bash curl --request POST \ --url https://api.unkey.dev/v1/keys.verifyKey \ --header 'Content-Type: application/json' \ --data '{ "key": "" }' ``` ```json { "keyId": "", "valid": true, "meta": {}, "remaining": 99 } ``` The returned `remaining` value represents how many verifications are remaining after the current one. A value of 3, means you can verify the key successfully 3 more times. # Usage limited keys Source: https://unkey.com/docs/apis/features/remaining Limiting the usage of keys Sometimes you would like to create an api key and automatically invalidate it after a certain number of uses. Example: You are selling API access and a customer has purchased 1000 api requests from you. Unkey allows you to set/update usage limits on individual keys and we take care of invalidating a key after it has reached its limit. ### Example Let's create a new key, which can be used 100 times. ```bash curl --request POST \ --url https://api.unkey.dev/v1/keys.createKey \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "apiId":"", "remaining": 100 }' ``` Now when you verify the new key, you will receive back the remaining verifications and after all of them are used up, the key is invalid. ```bash curl --request POST \ --url https://api.unkey.dev/v1/keys.verifyKey \ --header 'Content-Type: application/json' \ --data '{ "apiId":"", "key": "" }' ``` ```json { "valid": true, "remaining": 99 } ``` The returned `remaining` value represents how many verifications are remaining after the current one. A value of 3, means you can verify the key successfully 3 more times. ## Custom cost By default we deduct `1` from the remaining verifications, but in some cases you need to deduct more. You can override this in the request body. In this example unkey would deduct `4` for every valid verification. If a key would only have 3 remaining, the request would be rejected, as there is not enough remaining left. There is a special case when you set `cost = 0`. In this case, the request will always be valid, but will not deduct anything. ```bash {7-9} curl --request POST \ --url https://api.unkey.dev/v1/keys.verifyKey \ --header 'Content-Type: application/json' \ --data '{ "apiId":"", "key": "", "remaining": { "cost": 4 } }' ``` # Key Revocation Source: https://unkey.com/docs/apis/features/revocation Keys can be revoked at any time, from the API or the dashboard. In the event that a key is compromised, you can revoke it at any time. Once the key is revoked, it can take up to 60 seconds for the key to be invalidated. Once invalidated, the key will no longer be able to be used to authenticate requests. # Temporary Keys Source: https://unkey.com/docs/apis/features/temp-keys How to create temporary API Keys in Unkey ## What are temporary API Keys? Temporary API Keys are API Keys that expire after a certain amount of time. They are useful for when you want to give a user access to your API for a limited amount of time. For example, you might want to give a user access to your API for 1 hour, or 1 day, or 1 week. You can do this by creating a temporary API Key that expires after a certain amount of time. ## How to create a temporary API Key To create a temporary API Key, you need to make a `POST` request to the `/v1/keys` endpoint. You can read about all the parameters you can send in the [API Reference](/api-reference/keys/create). ```bash curl --request POST \ --url https://api.unkey.dev/v1/keys.createKey \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "apiId":"", "prefix":"xyz", "byteLength":16, "ownerId":"USER_ID", "expires": 1718718673000, }' ``` Once the key is created, you can send it to your user. They can then use it to access your API. Once the key expires, they will no longer be able to access your API and the key will be deleted. # IP Whitelisting Source: https://unkey.com/docs/apis/features/whitelist Unkey offers IP whitelisting to restrict requests to a specific set of IP addresses. This is useful for restricting access to your API to a specific set of IP addresses, such as your own servers or a set of trusted partners. This feature is available as an addon or with an Enterprise plan. IP Whitelist example # Overview Source: https://unkey.com/docs/apis/introduction Protect your public APIs Unkey provides a simple feature rich API key management system. You can use Unkey to protect your public APIs with ease. Below is an example of implementing Unkey in your API. ```ts Typescript import { verifyKey } from '@unkey/api'; const { result, error } = await verifyKey({ apiId: "api_123", key: "xyz_123" }) if ( error ) { // handle network error } if ( !result.valid ) { // reject unauthorized request } ``` ```py Python import asyncio import os import unkey async def main() -> None: client = unkey.Client(api_key=os.environ["API_KEY"]) await client.start() result = await client.keys.verify_key("prefix_abc123") if result.is_ok: print(data.valid) else: print(result.unwrap_err()) ``` ```go Golang package main import( "context" unkeygo "github.com/unkeyed/unkey-go" "github.com/unkeyed/unkey-go/models/components" "log" ) func main() { ctx := context.Background() s := unkeygo.New( unkeygo.WithSecurity("UNKEY_ROOT_KEY"), ) res, err := s.Keys.VerifyKey(ctx, components.V1KeysVerifyKeyRequest{ APIID: unkeygo.String("api_1234"), Key: "sk_1234", }) if err != nil { log.Fatal(err) } if res.V1KeysVerifyKeyResponse != nil { // handle response } } ``` ```bash cURL curl --request POST \ --url https://api.unkey.dev/v1/keys.verifyKey \ --header 'Content-Type: application/json' \ --data '{ "apiId": "api_1234", "key": "sk_1234" }' ``` ## Features Below are some of the key features of Unkey API key management system, for you to explore. Key based ratelimiting Set usage limits per key Keys that expire after a set time Refill your remaining keys on a set schedule Rich analytics on your API and keys Separate your keys into live and test environments Access Control with Roles and Permissions # Overview Source: https://unkey.com/docs/audit-log/introduction Audit logs for your workspace, allowing you to see the history of all the resource requests made inside your workspace. We automatically capture all mutations, including key creation, permission changes and configuration changes. ## Accessing Audit Logs To access the Audit Logs, click [here](https://app.unkey.com/audit) or on the **Audit Logs** option in the left navigation bar. # Audit logs in detail The audit logs table displays the following fields: * **Actor**: who was responsible for the change. This can be either a user (for actions taken in the web app) or a key (for actions taken via the API). * **Event**: the type of change. You can filter by type of events using the UI. Click to expand for more detail. * **Location**: the IP address of the actor who made the change. # Feature requests Need additional functionality from audit logs, beyond what is provided currently? [Get in touch](mailto:support@unkey.dev)! # Event Types Source: https://unkey.com/docs/audit-log/types Available audit log event types ## Workspaces Workspace actions that will create a new audit log item. * `workspace.create` - A workspace is created. * `workspace.update` - A workspace is updated. ## API API actions that will create a new audit log item. * `api.create` - An API is created. * `api.update` - An API is updated. * `api.delete` - An API is deleted. ## Keys Key actions that will create a new audit log item. * `key.create` - A key is created. * `key.update` - A key is updated. * `key.delete` - A key is deleted. ## Ratelimit Ratelimit actions that will create a new audit log item. ### Ratelimit Namespace * `ratelimitNamespace.update` - A ratelimit namespace is updated. * `ratelimitNamespace.update` - A ratelimit namespace is updated. * `ratelimitNamespace.delete` - A ratelimit namespace is deleted. ### Ratelimit Override * `ratelimitOverride.create` - A ratelimit override is created. * `ratelimitOverride.update` - A ratelimit override is updated. ## Role Role actions that will create a new audit log item. * `role.create` - A role is created. * `role.update` - A role is updated. * `role.delete` - A role is deleted. ## Permission Permission actions that will create a new audit log item. * `permission.create` - A permission is created. * `permission.update` - A permission is updated. * `permission.delete` - A permission is deleted. ## Authorization Authorization actions that will create a new audit log item. * `authorization.connect_role_and_permission` - A role and permission are connected * `authorization.disconnect_role_and_permissions` - A role and permission are disconnected. * `authorization.connect_role_and_key` - A role and key are connected. * `authorization.disconnect_role_and_key` - A role and key are disconnected. * `authorization.connect_permission_and_key` - A permission and key are connected. * `authorization.disconnect_permission_and_key` - A permission and key are disconnected. # Overview Source: https://unkey.com/docs/concepts/identities/overview 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 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 It is very common to issue multiple keys for the same user, but managing metadata and configuration for each key can be cumbersome and error-prone. By associating all keys with the same identity, you can share metadata and configuration across all keys. 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. ### 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 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. 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. # Ratelimits Source: https://unkey.com/docs/concepts/identities/ratelimits 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). ## Sharing ratelimits Identities allow you to share ratelimits across multiple keys. Let's say you want to limit a specific user to 100 requests per second: If you just set each key to `100 RPS` then the user can make `100 * number of keys` requests per second, which probably isn't what you want. Of course you could limit the number of keys a user can have or do some math to divide 100 by the number of keys they have, but that's not fixing the actual problem, it's just a workaround. Instead, you should create an identity for the user, set the ratelimit on the identity to `100 RPS` and then associate all keys of the user with the identity. This way, the user can only make `100 RPS` across all of their keys. ## Multiple ratelimits You can set multiple ratelimits for an identity and check against some or all of them when verifying a key. Let's say you are building an app that uses AI under the hood and you want to limit your customers to 500 requests per hour, but also ensure that they don't blow up your bill by using too many tokens. In this case you would create an identity for the user and then create two ratelimits: 1. `{name: "requests", limit: 500, duration: 3600000}` -> 500 requests per hour 2. `{name: "tokens", limit: 20000, duration: 86400000}` -> 20k tokens per day Now if either one of those limits is exceeded, the request is denied. API reference for verifying: [/api-reference/keys/verify](https://www.unkey.com/docs/api-reference/keys/verify) API reference for creating identities: [/api-reference/identities/create-identity](https://www.unkey.com/docs/api-reference/identities/create-identity) # Vercel Source: https://unkey.com/docs/integrations/vercel Zero Config API Authenciation on Vercel This integration is currently not supported, we have plans to bring it back in the future ## Prerequisites * Created your [Unkey account](https://app.unkey.com/auth/sign-up) * Created an API in the [Unkey dashboard](https://app.unkey.com/apis) * [Vercel account](https://vercel.com/signup) ## Adding Vercel Integration Prefer a video? Checkout this video that walks through the steps below.