openapi: 3.1.0
info:
description: "Unkey's API provides programmatic access for all resources within our platform.\n\n\n### Authentication\n#\nThis API uses HTTP Bearer authentication with root keys. Most endpoints require specific permissions associated with your root key. When making requests, include your root key in the `Authorization` header:\n```\nAuthorization: Bearer unkey_xxxxxxxxxxx\n```\n\nAll responses follow a consistent envelope structure that separates operational metadata from actual data. This design provides several benefits:\n- Debugging: Every response includes a unique requestId for tracing issues\n- Consistency: Predictable response format across all endpoints\n- Extensibility: Easy to add new metadata without breaking existing integrations\n- Error Handling: Unified error format with actionable information\n\n### Success Response Format:\n```json\n{\n \"meta\": {\n \"requestId\": \"req_123456\"\n },\n \"data\": {\n // Actual response data here\n }\n}\n```\n\nThe meta object contains operational information:\n- `requestId`: Unique identifier for this request (essential for support)\n\nThe data object contains the actual response data specific to each endpoint.\n\n### Paginated Response Format:\n```json\n{\n \"meta\": {\n \"requestId\": \"req_123456\"\n },\n \"data\": [\n // Array of results\n ],\n \"pagination\": {\n \"cursor\": \"next_page_token\",\n \"hasMore\": true\n }\n}\n```\n\nThe pagination object appears on list endpoints and contains:\n- `cursor`: Token for requesting the next page\n- `hasMore`: Whether more results are available\n\n### Error Response Format:\n```json\n{\n \"meta\": {\n \"requestId\": \"req_2c9a0jf23l4k567\"\n },\n \"error\": {\n \"detail\": \"The resource you are attempting to modify is protected and cannot be changed\",\n \"status\": 403,\n \"title\": \"Forbidden\",\n \"type\": \"https://unkey.com/docs/errors/unkey/application/protected_resource\"\n }\n}\n```\n\nError responses include comprehensive diagnostic information:\n- `title`: Human-readable error summary\n- `detail`: Specific description of what went wrong\n- `status`: HTTP status code\n- `type`: Link to error documentation\n- `errors`: Array of validation errors (for 400 responses)\n\nThis structure ensures you always have the context needed to debug issues and take corrective action."
title: Unkey analytics permissions API
version: 2.0.0
servers:
- url: https://api.unkey.com
security:
- rootKey: []
tags:
- description: Permission and role management operations
name: permissions
paths:
/v2/permissions.createPermission:
post:
description: 'Create a new permission to define specific actions or capabilities in your RBAC system. Permissions can be assigned directly to API keys or included in roles.
Use hierarchical naming patterns like `documents.read`, `admin.users.delete`, or `billing.invoices.create` for clear organization.
**Important:** Permission names must be unique within the workspace. Once created, permissions are immediately available for assignment.
**Required Permissions**
Your root key must have the following permission:
- `rbac.*.create_permission`
'
operationId: permissions.createPermission
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsCreatePermissionRequestBody'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsCreatePermissionResponseBody'
description: Permission created successfully
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequestErrorResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/UnauthorizedErrorResponse'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/ForbiddenErrorResponse'
description: Forbidden
'409':
content:
application/json:
schema:
$ref: '#/components/schemas/ConflictErrorResponse'
description: Conflict - permission with that name already exists
'429':
content:
application/problem+json:
schema:
$ref: '#/components/schemas/TooManyRequestsErrorResponse'
description: Too Many Requests
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/InternalServerErrorResponse'
description: Internal Server Error
security:
- rootKey: []
summary: Create Permission
tags:
- permissions
x-speakeasy-name-override: CreatePermission
/v2/permissions.createRole:
post:
description: 'Create a new role to group related permissions for easier management. Roles enable consistent permission assignment across multiple API keys.
**Important:** Role names must be unique within the workspace. Once created, roles are immediately available for assignment.
**Required Permissions**
Your root key must have the following permission:
- `rbac.*.create_role`
'
operationId: permissions.createRole
requestBody:
content:
application/json:
examples:
basic:
summary: Basic role creation
value:
description: Can read and write content
name: content.editor
withoutDescription:
summary: Role without description
value:
name: api.reader
schema:
$ref: '#/components/schemas/V2PermissionsCreateRoleRequestBody'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsCreateRoleResponseBody'
description: Role created successfully
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequestErrorResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/UnauthorizedErrorResponse'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/ForbiddenErrorResponse'
description: Forbidden
'409':
content:
application/json:
schema:
$ref: '#/components/schemas/ConflictErrorResponse'
description: Conflict - A role with this name already exists
'429':
content:
application/problem+json:
schema:
$ref: '#/components/schemas/TooManyRequestsErrorResponse'
description: Too Many Requests
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/InternalServerErrorResponse'
description: Internal Server Error
security:
- rootKey: []
summary: Create Role
tags:
- permissions
x-speakeasy-name-override: CreateRole
/v2/permissions.deletePermission:
post:
description: 'Remove a permission from your workspace. This also removes the permission from all API keys and roles.
**Important:** This operation cannot be undone and immediately affects all API keys and roles that had this permission assigned.
**Required Permissions**
Your root key must have the following permission:
- `rbac.*.delete_permission`
'
operationId: permissions.deletePermission
requestBody:
content:
application/json:
examples:
basic:
summary: Delete a permission
value:
permissionId: perm_1234567890abcdef
schema:
$ref: '#/components/schemas/V2PermissionsDeletePermissionRequestBody'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsDeletePermissionResponseBody'
description: Permission deleted successfully
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequestErrorResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/UnauthorizedErrorResponse'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/ForbiddenErrorResponse'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/NotFoundErrorResponse'
description: Not Found - The specified permission does not exist
'429':
content:
application/problem+json:
schema:
$ref: '#/components/schemas/TooManyRequestsErrorResponse'
description: Too Many Requests
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/InternalServerErrorResponse'
description: Internal Server Error
security:
- rootKey: []
summary: Delete Permission
tags:
- permissions
x-speakeasy-name-override: DeletePermission
/v2/permissions.deleteRole:
post:
description: 'Remove a role from your workspace. This also removes the role from all assigned API keys.
**Important:** This operation cannot be undone and immediately affects all API keys that had this role assigned.
**Required Permissions**
Your root key must have the following permission:
- `rbac.*.delete_role`
'
operationId: permissions.deleteRole
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsDeleteRoleRequestBody'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsDeleteRoleResponseBody'
description: Role deleted successfully
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequestErrorResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/UnauthorizedErrorResponse'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/ForbiddenErrorResponse'
description: Forbidden
'429':
content:
application/problem+json:
schema:
$ref: '#/components/schemas/TooManyRequestsErrorResponse'
description: Too Many Requests
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/InternalServerErrorResponse'
description: Internal Server Error
security:
- rootKey: []
summary: Delete Role
tags:
- permissions
x-speakeasy-name-override: DeleteRole
/v2/permissions.getPermission:
post:
description: 'Retrieve details about a specific permission including its name, description, and metadata.
**Required Permissions**
Your root key must have the following permission:
- `rbac.*.read_permission`
'
operationId: permissions.getPermission
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsGetPermissionRequestBody'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsGetPermissionResponseBody'
description: Permission retrieved successfully
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequestErrorResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/UnauthorizedErrorResponse'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/ForbiddenErrorResponse'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/NotFoundErrorResponse'
description: Not Found
'429':
content:
application/problem+json:
schema:
$ref: '#/components/schemas/TooManyRequestsErrorResponse'
description: Too Many Requests
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/InternalServerErrorResponse'
description: Internal Server Error
security:
- rootKey: []
summary: Get Permission
tags:
- permissions
x-speakeasy-name-override: GetPermission
/v2/permissions.getRole:
post:
description: 'Retrieve details about a specific role including its assigned permissions.
**Required Permissions**
Your root key must have the following permission:
- `rbac.*.read_role`
'
operationId: permissions.getRole
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsGetRoleRequestBody'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsGetRoleResponseBody'
description: Role retrieved successfully
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequestErrorResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/UnauthorizedErrorResponse'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/ForbiddenErrorResponse'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/NotFoundErrorResponse'
description: Not Found
'429':
content:
application/problem+json:
schema:
$ref: '#/components/schemas/TooManyRequestsErrorResponse'
description: Too Many Requests
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/InternalServerErrorResponse'
description: Internal Server Error
security:
- rootKey: []
summary: Get Role
tags:
- permissions
x-speakeasy-name-override: GetRole
/v2/permissions.listPermissions:
post:
description: 'Retrieve all permissions in your workspace.
Results are paginated and sorted by their id.
**Required Permissions**
Your root key must have the following permission:
- `rbac.*.read_permission`
'
operationId: permissions.listPermissions
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsListPermissionsRequestBody'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsListPermissionsResponseBody'
description: Permissions retrieved successfully
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequestErrorResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/UnauthorizedErrorResponse'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/ForbiddenErrorResponse'
description: Forbidden
'429':
content:
application/problem+json:
schema:
$ref: '#/components/schemas/TooManyRequestsErrorResponse'
description: Too Many Requests
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/InternalServerErrorResponse'
description: Internal Server Error
security:
- rootKey: []
summary: List Permissions
tags:
- permissions
x-speakeasy-name-override: ListPermissions
/v2/permissions.listRoles:
post:
description: 'Retrieve all roles in your workspace including their assigned permissions.
Results are paginated and sorted by their id.
**Required Permissions**
Your root key must have the following permission:
- `rbac.*.read_role`
'
operationId: permissions.listRoles
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsListRolesRequestBody'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/V2PermissionsListRolesResponseBody'
description: Roles retrieved successfully
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/BadRequestErrorResponse'
description: Bad Request
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/UnauthorizedErrorResponse'
description: Unauthorized
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/ForbiddenErrorResponse'
description: Forbidden
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/NotFoundErrorResponse'
description: Not Found
'429':
content:
application/problem+json:
schema:
$ref: '#/components/schemas/TooManyRequestsErrorResponse'
description: Too Many Requests
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/InternalServerErrorResponse'
description: Internal Server Error
security:
- rootKey: []
summary: List Roles
tags:
- permissions
x-speakeasy-name-override: ListRoles
components:
schemas:
V2PermissionsDeleteRoleRequestBody:
type: object
required:
- role
properties:
role:
type: string
pattern: ^[a-zA-Z0-9_:\-\.\*]+$
minLength: 3
maxLength: 255
description: 'Unique identifier of the role to permanently delete from your workspace.
Must either be a valid role ID that begins with ''role_'' or the given role name and exists within your workspace.
WARNING: Deletion is immediate and irreversible with significant consequences:
- All API keys assigned this role will lose the associated permissions
- Access to resources protected by this role''s permissions will be denied
- Any authorization logic depending on this role will start failing
- Historical analytics referencing this role remain intact
Before deletion, ensure:
- You''ve updated any dependent authorization logic or code
- You''ve migrated any keys to use alternative roles or direct permissions
- You''ve notified relevant team members of the access changes
'
example: role_dns_manager
additionalProperties: false
V2PermissionsListRolesRequestBody:
type: object
properties:
limit:
type: integer
minimum: 1
maximum: 100
default: 100
description: 'Maximum number of roles to return in a single response.
Use smaller values for faster response times and better UI performance.
Use larger values when you need to process many roles efficiently.
Results exceeding this limit will be paginated with a cursor for continuation.
'
example: 50
cursor:
type: string
maxLength: 1024
description: 'Pagination cursor from a previous response to fetch the next page of roles.
Include this when you need to retrieve additional roles beyond the first page.
Each response containing more results will include a cursor value that can be used here.
Leave empty or omit this field to start from the beginning of the role list.
'
example: eyJrZXkiOiJyb2xlXzEyMzQifQ==
additionalProperties: false
V2PermissionsDeletePermissionResponseBody:
type: object
required:
- meta
- data
properties:
meta:
$ref: '#/components/schemas/Meta'
data:
$ref: '#/components/schemas/EmptyResponse'
additionalProperties: false
ValidationError:
additionalProperties: false
properties:
location:
description: 'JSON path indicating exactly where in the request the error occurred. This helps pinpoint the problematic field or parameter. Examples include:
- ''body.name'' (field in request body)
- ''body.items[3].tags'' (nested array element)
- ''path.apiId'' (path parameter)
- ''query.limit'' (query parameter)
Use this location to identify exactly which part of your request needs correction.'
type: string
example: body.permissions[0].name
message:
description: Detailed error message explaining what validation rule was violated. This provides specific information about why the field or parameter was rejected, such as format errors, invalid values, or constraint violations.
type: string
example: Must be at least 3 characters long
fix:
description: A human-readable suggestion describing how to fix the error. This provides practical guidance on what changes would satisfy the validation requirements. Not all validation errors include fix suggestions, but when present, they offer specific remediation advice.
type: string
example: Ensure the name uses only alphanumeric characters, underscores, and hyphens
required:
- location
- message
type: object
description: Individual validation error details. Each validation error provides precise information about what failed, where it failed, and how to fix it, enabling efficient error resolution.
Meta:
type: object
required:
- requestId
properties:
requestId:
description: A unique id for this request. Always include this ID when contacting support about a specific API request. This identifier allows Unkey's support team to trace the exact request through logs and diagnostic systems to provide faster assistance.
example: req_123
type: string
additionalProperties: false
description: Metadata object included in every API response. This provides context about the request and is essential for debugging, audit trails, and support inquiries. The `requestId` is particularly important when troubleshooting issues with the Unkey support team.
BadRequestErrorDetails:
allOf:
- $ref: '#/components/schemas/BaseError'
- type: object
properties:
errors:
description: List of individual validation errors that occurred in the request. Each error provides specific details about what failed validation, where the error occurred in the request, and suggestions for fixing it. This granular information helps developers quickly identify and resolve multiple issues in a single request without having to make repeated API calls.
items:
$ref: '#/components/schemas/ValidationError'
type: array
required:
- errors
description: Extended error details specifically for bad request (400) errors. This builds on the BaseError structure by adding an array of individual validation errors, making it easy to identify and fix multiple issues at once.
NotFoundErrorResponse:
type: object
required:
- meta
- error
properties:
meta:
$ref: '#/components/schemas/Meta'
error:
$ref: '#/components/schemas/BaseError'
description: 'Error response when the requested resource cannot be found. This occurs when:
- The specified resource ID doesn''t exist in your workspace
- The resource has been deleted or moved
- The resource exists but is not accessible with current permissions
To resolve this error, verify the resource ID is correct and that you have access to it.'
UnauthorizedErrorResponse:
type: object
required:
- meta
- error
properties:
meta:
$ref: '#/components/schemas/Meta'
error:
$ref: '#/components/schemas/BaseError'
description: 'Error response when authentication has failed or credentials are missing. This occurs when:
- No authentication token is provided in the request
- The provided token is invalid, expired, or malformed
- The token format doesn''t match expected patterns
To resolve this error, ensure you''re including a valid root key in the Authorization header.'
V2PermissionsListRolesResponseData:
type: array
maxItems: 1000
description: Array of roles with their assigned permissions.
items:
$ref: '#/components/schemas/Role'
V2PermissionsGetPermissionRequestBody:
type: object
required:
- permission
properties:
permission:
type: string
minLength: 3
maxLength: 255
pattern: ^[a-zA-Z][a-zA-Z0-9._-]*$
description: 'The unique identifier of the permission to retrieve. Must be a valid permission ID that begins with ''perm_'' and exists within your workspace.
'
example: perm_1234567890abcdef
additionalProperties: false
V2PermissionsCreateRoleResponseData:
type: object
properties:
roleId:
type: string
minLength: 3
maxLength: 255
pattern: ^[a-zA-Z0-9_]+$
description: 'The unique identifier assigned to the newly created role.
Use this ID to reference the role in permission assignments, key operations, and role management calls.
Always begins with ''role_'' followed by a unique alphanumeric sequence.
Store this ID if you need to manage, modify, or assign this role in future operations.
'
example: role_1234567890abcdef
required:
- roleId
additionalProperties: false
Pagination:
type: object
properties:
cursor:
type: string
minLength: 1
maxLength: 1024
description: 'Opaque pagination token for retrieving the next page of results.
Include this exact value in the cursor field of subsequent requests.
Cursors are temporary and may expire after extended periods.
'
example: eyJrZXkiOiJrZXlfMTIzNCIsInRzIjoxNjk5Mzc4ODAwfQ==
hasMore:
type: boolean
description: 'Indicates whether additional results exist beyond this page.
When true, use the cursor to fetch the next page.
When false, you have reached the end of the result set.
'
example: true
required:
- hasMore
additionalProperties: false
description: Pagination metadata for list endpoints. Provides information necessary to traverse through large result sets efficiently using cursor-based pagination.
V2PermissionsGetPermissionResponseBody:
type: object
required:
- meta
- data
properties:
meta:
$ref: '#/components/schemas/Meta'
data:
$ref: '#/components/schemas/Permission'
additionalProperties: false
V2PermissionsCreateRoleRequestBody:
type: object
required:
- name
properties:
name:
type: string
minLength: 1
maxLength: 512
pattern: ^[a-zA-Z][a-zA-Z0-9._-]*$
description: 'The unique name for this role. Must be unique within your workspace and clearly indicate the role''s purpose. Use descriptive names like ''admin'', ''editor'', or ''billing_manager''.
Examples: ''admin.billing'', ''support.readonly'', ''developer.api'', ''manager.analytics''
'
example: support.readonly
description:
type: string
maxLength: 512
description: 'Provides comprehensive documentation of what this role encompasses and what access it grants.
Include information about the intended use case, what permissions should be assigned, and any important considerations.
This internal documentation helps team members understand role boundaries and security implications.
Not visible to end users - designed for administration teams and access control audits.
Consider documenting:
- The role''s intended purpose and scope
- What types of users should receive this role
- What permissions are typically associated with it
- Any security considerations or limitations
- Related roles that might be used together
'
example: Provides read-only access for customer support representatives. Includes permissions to view user accounts, support tickets, and basic analytics. Does not include access to billing, admin functions, or data modification capabilities.
additionalProperties: false
V2PermissionsCreatePermissionResponseData:
type: object
properties:
permissionId:
type: string
minLength: 3
maxLength: 255
pattern: ^[a-zA-Z0-9_]+$
description: 'The unique identifier assigned to the newly created permission.
Use this ID to reference the permission in role assignments, key operations, and other API calls.
Always begins with ''perm_'' followed by a unique alphanumeric sequence.
Store this ID if you need to manage or reference this permission in future operations.
'
example: perm_1234567890abcdef
required:
- permissionId
additionalProperties: false
TooManyRequestsErrorResponse:
type: object
required:
- meta
# --- truncated at 32 KB (50 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/unkey/refs/heads/main/openapi/unkey-permissions-api-openapi.yml