openapi: 3.0.3 info: title: Coval Agents API Keys API version: 1.0.0 description: ' Manage configurations for simulations and evaluations. ' contact: name: Coval API Support email: support@coval.dev url: https://docs.coval.ai license: name: Proprietary url: https://coval.dev/terms servers: - url: https://api.coval.dev/v1 description: Production API security: - ApiKeyAuth: [] tags: - name: API Keys description: Manage API keys for your organization paths: /api-keys: post: operationId: createApiKey summary: Create API key description: Create a new API key. The full key value is only returned once in this response. tags: - API Keys security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateApiKeyRequest' examples: minimal: $ref: '#/components/examples/CreateApiKeyMinimal' withName: $ref: '#/components/examples/CreateApiKeyWithName' restrictedPermissions: $ref: '#/components/examples/CreateApiKeyRestrictedPermissions' responses: '201': description: API key created successfully content: application/json: schema: $ref: '#/components/schemas/CreateApiKeyResponse' examples: created: $ref: '#/components/examples/ApiKeyCreated' '400': description: Invalid request body or validation failed content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: invalidKeyType: $ref: '#/components/examples/InvalidKeyTypeError' nameTooLong: $ref: '#/components/examples/NameTooLongError' '403': $ref: '#/components/responses/PermissionDenied' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalError' get: operationId: listApiKeys summary: List API keys description: List API keys for your organization. Returns ACTIVE keys by default. tags: - API Keys security: - ApiKeyAuth: [] parameters: - name: status in: query required: false schema: type: string description: 'Comma-separated list of statuses to filter by. **Supported values:** `ACTIVE`, `REVOKED`, `SUSPENDED`, `EXPIRED` If not provided, defaults to showing only `ACTIVE` keys. ' examples: activeOnly: value: ACTIVE summary: Active keys only (default behavior) multipleStatuses: value: ACTIVE,SUSPENDED summary: Active and suspended keys allStatuses: value: ACTIVE,REVOKED,SUSPENDED,EXPIRED summary: All keys regardless of status - name: page_size in: query required: false schema: type: integer minimum: 1 maximum: 100 default: 20 description: Maximum number of results per page example: 20 - name: page_token in: query required: false schema: type: string description: Pagination token from previous response. example: eyJvZmZzZXQiOjIwfQ== responses: '200': description: API keys retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ListApiKeysResponse' examples: success: $ref: '#/components/examples/ListApiKeysSuccess' '403': $ref: '#/components/responses/PermissionDenied' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalError' /api-keys/{api_key_id}: patch: operationId: updateApiKeyStatus summary: Update API key status description: Update the status of an API key. REVOKED is a terminal state. tags: - API Keys security: - ApiKeyAuth: [] parameters: - name: api_key_id in: path required: true schema: type: string pattern: ^[0-9A-Z]{26}$ description: API key resource ID (ULID, 26 characters) example: 01HX2ABC3DEF4GHI5JKL6MNO7P requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateApiKeyRequest' examples: revokeKey: $ref: '#/components/examples/UpdateApiKeyRevoke' suspendKey: $ref: '#/components/examples/UpdateApiKeySuspend' reactivateKey: $ref: '#/components/examples/UpdateApiKeyReactivate' responses: '200': description: API key status updated successfully content: application/json: schema: $ref: '#/components/schemas/UpdateApiKeyResponse' examples: updated: $ref: '#/components/examples/ApiKeyUpdated' '400': description: Invalid status transition or request body content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: invalidTransition: $ref: '#/components/examples/InvalidTransitionError' invalidStatus: $ref: '#/components/examples/InvalidStatusError' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/PermissionDenied' '404': description: API key not found or belongs to different organization content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: notFound: $ref: '#/components/examples/ApiKeyNotFoundError' '500': $ref: '#/components/responses/InternalError' delete: operationId: deleteApiKey summary: Delete API key description: Permanently delete an API key. This action cannot be undone. tags: - API Keys security: - ApiKeyAuth: [] parameters: - name: api_key_id in: path required: true schema: type: string pattern: ^[0-9A-Z]{26}$ description: API key resource ID (ULID, 26 characters) example: 01HX2ABC3DEF4GHI5JKL6MNO7P responses: '204': description: API key deleted successfully (no content) '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/PermissionDenied' '404': description: API key not found or belongs to different organization content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: notFound: $ref: '#/components/examples/ApiKeyNotFoundError' '500': $ref: '#/components/responses/InternalError' components: responses: InternalError: description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: INTERNAL message: Internal server error details: - description: An unexpected error occurred Unauthorized: description: Authentication failed content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: UNAUTHENTICATED message: Authentication failed details: - field: X-API-Key description: Invalid or missing API key PermissionDenied: description: API key lacks required permission scope content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: PERMISSION_DENIED message: Insufficient permissions details: - field: permissions description: 'API key does not have required permission: api-keys:write' examples: UpdateApiKeySuspend: summary: Suspend an API key description: Temporarily disable a key. Can be reactivated later. value: status: SUSPENDED reason: Temporarily disabling for security audit InvalidTransitionError: summary: Invalid status transition value: error: code: INVALID_ARGUMENT message: Invalid status transition details: - field: status description: Cannot transition from REVOKED to ACTIVE. REVOKED is a terminal state. ApiKeyCreated: summary: API key created successfully (unmasked) value: api_key: id: 01HX2ABC3DEF4GHI5JKL6MNO7P organization_id: caf26438 api_key: coval_sk_prod_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 key_type: SERVICE status: ACTIVE name: Production Service Key description: Primary key for production backend service authentication permissions: [] create_time: '2025-10-14T12:00:00Z' update_time: null last_used_at: null CreateApiKeyMinimal: summary: Create API key with defaults description: Creates a SERVICE key with full access. All fields are optional. value: {} CreateApiKeyRestrictedPermissions: summary: Create key with restricted permissions description: Create a user key with specific permission scopes. value: name: Read-Only Key description: Limited access key for reading runs, agents, and metrics key_type: USER permissions: - runs:read - agents:read - metrics:read CreateApiKeyWithName: summary: Create named API key description: Create a service key with a descriptive name. value: name: Production Service Key description: Primary key for production backend service authentication ApiKeyUpdated: summary: API key status updated successfully (masked) value: api_key: id: 01HX2ABC3DEF4GHI5JKL6MNO7P organization_id: caf26438 api_key: '****-****-****-o5p6' key_type: SERVICE status: REVOKED name: Production Service Key description: Primary key for production backend service authentication permissions: [] create_time: '2025-10-14T12:00:00Z' update_time: '2025-10-23T16:45:00Z' last_used_at: '2025-10-16T09:15:00Z' NameTooLongError: summary: Name exceeds maximum length value: error: code: INVALID_ARGUMENT message: Invalid request body details: - field: name description: name must be at most 200 characters UpdateApiKeyRevoke: summary: Revoke an API key description: Permanently revoke a key (terminal state, cannot be undone). value: status: REVOKED reason: Key compromised, revoking as a precaution ListApiKeysSuccess: summary: Successful list response value: api_keys: - id: 01HX2ABC3DEF4GHI5JKL6MNO7P organization_id: caf26438 api_key: '****-****-****-o5p6' key_type: SERVICE status: ACTIVE name: Production Service Key description: Primary key for production backend service authentication permissions: [] create_time: '2025-10-14T12:00:00Z' update_time: '2025-10-15T14:30:00Z' last_used_at: '2025-10-16T09:15:00Z' - id: 01HX3DEF4GHI5JKL6MNO7PQR8S organization_id: caf26438 api_key: '****-****-****-q9r0' key_type: USER status: ACTIVE name: Staging Test Key description: Key for staging environment testing permissions: - runs:read - runs:write create_time: '2025-10-13T08:00:00Z' update_time: null last_used_at: '2025-10-14T11:45:00Z' next_page_token: eyJvZmZzZXQiOjIwfQ== total_count: 42 ApiKeyNotFoundError: summary: API key not found value: error: code: NOT_FOUND message: API key not found details: - field: api_key_id description: API key not found or not accessible by your organization InvalidKeyTypeError: summary: Invalid key type value: error: code: INVALID_ARGUMENT message: Invalid request body details: - field: key_type description: Input should be 'SERVICE' or 'USER' InvalidStatusError: summary: Invalid status value value: error: code: INVALID_ARGUMENT message: Invalid request body details: - field: status description: Input should be 'ACTIVE', 'REVOKED', 'SUSPENDED', or 'EXPIRED' UpdateApiKeyReactivate: summary: Reactivate a suspended or expired key description: Reactivate a key that was previously suspended or expired. value: status: ACTIVE reason: Security audit complete, reactivating key schemas: CreateApiKeyRequest: type: object properties: name: type: string nullable: true description: Human-readable name for the API key maxLength: 200 example: Production Service Key description: type: string nullable: true description: Detailed description of the API key purpose maxLength: 2000 example: Primary key for production backend service authentication key_type: allOf: - $ref: '#/components/schemas/KeyType' default: SERVICE permissions: type: array description: Permission scopes to grant. Empty array (default) grants full access. items: $ref: '#/components/schemas/PermissionScope' default: [] example: [] KeyType: type: string description: 'Type of API key. - **SERVICE**: Machine-to-machine authentication for backend services and integrations - **USER**: User-scoped key tied to individual user actions ' enum: - SERVICE - USER example: SERVICE PermissionScope: type: string description: 'Permission scope. Format: resource:action, resource:*, or * for full access. Empty array [] grants full access. ' enum: - '*' - runs:read - runs:write - runs:* - agents:read - agents:write - agents:* - conversations:read - conversations:submit - conversations:* - metrics:read - metrics:* - test-sets:read - test-sets:write - test-sets:* - test-cases:read - test-cases:write - test-cases:* - personas:read - personas:write - personas:delete - personas:* - simulations:read - simulations:write - simulations:* - traces:read - traces:* - dashboards:read - dashboards:write - dashboards:delete - dashboards:* - api-keys:read - api-keys:write - api-keys:delete - api-keys:* - scheduled-runs:read - scheduled-runs:write - scheduled-runs:delete - scheduled-runs:* - run-templates:read - run-templates:write - run-templates:delete - run-templates:* - reports:read - reports:write - reports:delete - reports:* ListApiKeysResponse: type: object required: - api_keys - total_count properties: api_keys: type: array description: List of API key resources (masked) items: $ref: '#/components/schemas/ApiKeyResource' next_page_token: type: string nullable: true description: Token for fetching next page (null if no more results) example: eyJvZmZzZXQiOjIwfQ== total_count: type: integer description: Total number of API keys matching the filter criteria example: 42 ErrorResponse: type: object description: Standard error response required: - error properties: error: type: object required: - code - message - details properties: code: type: string description: Error code enum enum: - INVALID_ARGUMENT - UNAUTHENTICATED - PERMISSION_DENIED - NOT_FOUND - INTERNAL example: INVALID_ARGUMENT message: type: string description: Human-readable error message example: Invalid request parameter details: type: array description: Detailed error information items: type: object properties: field: type: string nullable: true description: Field name that caused the error example: status description: type: string description: Detailed error description example: Invalid status value UpdateApiKeyRequest: type: object required: - status description: Update the status of an API key. properties: status: $ref: '#/components/schemas/ApiKeyStatus' reason: type: string nullable: true description: Reason for the status change (for audit purposes) maxLength: 2000 example: Key compromised, revoking as a precaution ApiKeyResourceUnmasked: type: object description: API key resource with full key value. Only returned during creation. properties: id: type: string description: API key resource ID (ULID, 26 characters) pattern: ^[0-9A-Z]{26}$ example: 01HX2ABC3DEF4GHI5JKL6MNO7P organization_id: type: string description: Organization ID that owns this API key example: caf26438 api_key: type: string description: The full API key value. Store it securely -- it cannot be retrieved again. example: coval_sk_prod_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 key_type: $ref: '#/components/schemas/KeyType' status: $ref: '#/components/schemas/ApiKeyStatus' name: type: string nullable: true description: Human-readable name for the API key maxLength: 200 example: Production Service Key description: type: string nullable: true description: Detailed description of the API key purpose maxLength: 2000 example: Primary key for production backend service authentication permissions: type: array description: 'Permission scopes granted to this key. Empty array grants full access. See `PermissionScope` for valid values. ' items: $ref: '#/components/schemas/PermissionScope' example: [] create_time: type: string format: date-time description: Creation timestamp (ISO 8601) example: '2025-10-14T12:00:00Z' update_time: type: string format: date-time nullable: true description: Last update timestamp (ISO 8601) example: null last_used_at: type: string format: date-time nullable: true description: Timestamp of last API key usage (ISO 8601) example: null UpdateApiKeyResponse: type: object required: - api_key properties: api_key: $ref: '#/components/schemas/ApiKeyResource' ApiKeyResource: type: object description: API key resource. Key values are masked except during creation. properties: id: type: string description: API key resource ID (ULID, 26 characters) pattern: ^[0-9A-Z]{26}$ example: 01HX2ABC3DEF4GHI5JKL6MNO7P organization_id: type: string description: Organization ID that owns this API key example: caf26438 api_key: type: string description: The API key value (masked except during creation). example: '****-****-****-a1b2' key_type: $ref: '#/components/schemas/KeyType' status: $ref: '#/components/schemas/ApiKeyStatus' name: type: string nullable: true description: Human-readable name for the API key maxLength: 200 example: Production Service Key description: type: string nullable: true description: Detailed description of the API key purpose maxLength: 2000 example: Primary key for production backend service authentication permissions: type: array description: 'Permission scopes granted to this key. Empty array grants full access. See `PermissionScope` for valid values. ' items: $ref: '#/components/schemas/PermissionScope' example: [] create_time: type: string format: date-time description: Creation timestamp (ISO 8601) example: '2025-10-14T12:00:00Z' update_time: type: string format: date-time nullable: true description: Last update timestamp (ISO 8601) example: '2025-10-15T14:30:00Z' last_used_at: type: string format: date-time nullable: true description: Timestamp of last API key usage (ISO 8601) example: '2025-10-16T09:15:00Z' ApiKeyStatus: type: string description: 'Current status of the API key. - **ACTIVE**: Key is active and can be used for authentication - **REVOKED**: Key has been permanently revoked (terminal state) - **SUSPENDED**: Key is temporarily disabled and can be reactivated - **EXPIRED**: Key has expired and can be reactivated ' enum: - ACTIVE - REVOKED - SUSPENDED - EXPIRED example: ACTIVE CreateApiKeyResponse: type: object required: - api_key properties: api_key: $ref: '#/components/schemas/ApiKeyResourceUnmasked' securitySchemes: ApiKeyAuth: type: apiKey in: header name: x-api-key description: API key for authentication x-visibility: external