{ "openapi": "3.1.0", "info": { "title": "Hadrian Gateway API", "description": "**Hadrian Gateway** is an AI Gateway providing a unified OpenAI-compatible API for routing requests to multiple LLM providers.\n\n## Overview\n\nThe gateway provides two main API surfaces:\n\n- **Public API** (`/api/v1/*`) - OpenAI-compatible endpoints for LLM inference. Use these endpoints to create chat completions, text completions, embeddings, and list available models. Authentication depends on the configured `auth.mode` (API key, IdP, IAP, or none).\n\n- **Admin API** (`/admin/v1/*`) - RESTful management endpoints for multi-tenant configuration. Manage organizations, projects, users, API keys, dynamic providers, usage tracking, and model pricing.\n\n## Authentication\n\nThe gateway supports multiple authentication methods for API access.\n\n### API Key Authentication\n\nAPI keys are the primary authentication method for programmatic access. Keys are created via the Admin API and scoped to organizations, projects, or users.\n\n**Using the Authorization header (recommended):**\n```\nAuthorization: Bearer gw_live_abc123def456...\n```\n\n**Using the X-API-Key header:**\n```\nX-API-Key: gw_live_abc123def456...\n```\n\nBoth headers are supported. The `Authorization: Bearer` format is recommended for compatibility with OpenAI client libraries.\n\n**Example request:**\n```bash\ncurl https://gateway.example.com/api/v1/chat/completions \\\n -H \\\"Authorization: Bearer gw_live_abc123def456...\\\" \\\n -H \\\"Content-Type: application/json\\\" \\\n -d '{\\\"model\\\": \\\"openai/gpt-4\\\", \\\"messages\\\": [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"Hello\\\"}]}'\n```\n\n### JWT Authentication\n\nWhen JWT authentication is enabled, requests can be authenticated using a JWT token from your identity provider.\n\n```\nAuthorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...\n```\n\nThe gateway validates the JWT against the configured JWKS endpoint and extracts the identity from the token claims.\n\n**Example request:**\n```bash\ncurl https://gateway.example.com/api/v1/chat/completions \\\n -H \\\"Authorization: Bearer eyJhbGciOiJSUzI1NiIs...\\\" \\\n -H \\\"Content-Type: application/json\\\" \\\n -d '{\\\"model\\\": \\\"openai/gpt-4\\\", \\\"messages\\\": [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"Hello\\\"}]}'\n```\n\n### Multi-Auth Mode\n\nWhen configured for multi-auth, the gateway accepts both API keys and JWTs using **format-based detection**:\n\n- **X-API-Key header**: Always validated as an API key\n- **Authorization: Bearer header**: Uses format-based detection:\n - Tokens starting with the configured API key prefix (default: `gw_`) are validated as API keys\n - All other tokens are validated as JWTs\n\n**Important:** Providing both `X-API-Key` and `Authorization` headers simultaneously results in a 400 error (ambiguous credentials). Choose one authentication method per request.\n\n**Examples:**\n```bash\n# API key in X-API-Key header\ncurl -H \\\"X-API-Key: gw_live_abc123...\\\" https://gateway.example.com/v1/chat/completions\n\n# API key in Authorization: Bearer header (format-based detection)\ncurl -H \\\"Authorization: Bearer gw_live_abc123...\\\" https://gateway.example.com/v1/chat/completions\n\n# JWT in Authorization: Bearer header\ncurl -H \\\"Authorization: Bearer eyJhbGciOiJSUzI1NiIs...\\\" https://gateway.example.com/v1/chat/completions\n```\n\n### Authentication Errors\n\n| Error Code | HTTP Status | Description | Example Response |\n|------------|-------------|-------------|------------------|\n| `unauthorized` | 401 | No authentication credentials provided | `{\\\"error\\\": {\\\"code\\\": \\\"unauthorized\\\", \\\"message\\\": \\\"Authentication required\\\"}}` |\n| `ambiguous_credentials` | 400 | Both X-API-Key and Authorization headers provided | `{\\\"error\\\": {\\\"code\\\": \\\"ambiguous_credentials\\\", \\\"message\\\": \\\"Ambiguous credentials: provide either X-API-Key or Authorization header, not both\\\"}}` |\n| `invalid_api_key` | 401 | API key is invalid, malformed, or revoked | `{\\\"error\\\": {\\\"code\\\": \\\"invalid_api_key\\\", \\\"message\\\": \\\"Invalid API key\\\"}}` |\n| `not_authenticated` | 401 | JWT validation failed | `{\\\"error\\\": {\\\"code\\\": \\\"not_authenticated\\\", \\\"message\\\": \\\"Token validation failed\\\"}}` |\n| `forbidden` | 403 | Valid credentials but insufficient permissions | `{\\\"error\\\": {\\\"code\\\": \\\"forbidden\\\", \\\"message\\\": \\\"Insufficient permissions\\\"}}` |\n\n### Configuration Examples\n\n**API Key Authentication:**\n```toml\n[auth.mode]\ntype = \\\"api_key\\\"\n\n[auth.api_key]\nheader_name = \\\"X-API-Key\\\" # Header to read API key from\nkey_prefix = \\\"gw_\\\" # Valid key prefix\ncache_ttl_secs = 60 # Cache key lookups for 60 seconds\n```\n\n**IdP Authentication (SSO + API keys + JWT):**\n```toml\n[auth.mode]\ntype = \\\"idp\\\"\n\n[auth.api_key]\nheader_name = \\\"X-API-Key\\\"\nkey_prefix = \\\"gw_\\\"\n\n[auth.session]\nsecure = true\n```\n\n**Identity-Aware Proxy (IAP):**\n```toml\n[auth.mode]\ntype = \\\"iap\\\"\nidentity_header = \\\"X-Forwarded-User\\\"\nemail_header = \\\"X-Forwarded-Email\\\"\n```\n\n## Pagination\n\nAll Admin API list endpoints use **cursor-based pagination** for stable, performant navigation.\n\n**Query Parameters:**\n- `limit` (optional): Maximum records per page (default: 100, max: 1000)\n- `cursor` (optional): Opaque cursor from previous response's `next_cursor` or `prev_cursor`\n- `direction` (optional): `forward` (default) or `backward`\n\n**Response:**\n```json\n{\n \\\"data\\\": [...],\n \\\"pagination\\\": {\n \\\"limit\\\": 100,\n \\\"has_more\\\": true,\n \\\"next_cursor\\\": \\\"MTczMzU4MDgwMDAwMDphYmMxMjM0...\\\",\n \\\"prev_cursor\\\": null\n }\n}\n```\n\n## Model Routing\n\nModels can be addressed in several ways:\n\n- **Static routing**: `provider-name/model-name` routes to config-defined providers\n- **Dynamic routing**: `:org/{ORG}/{PROVIDER}/{MODEL}` routes to database-backed providers\n- **Default**: When no prefix is specified, routes to the default provider\n\n## Error Codes\n\nAll errors follow a consistent JSON format:\n\n```json\n{\n \\\"error\\\": {\n \\\"code\\\": \\\"error_code\\\",\n \\\"message\\\": \\\"Human-readable error message\\\",\n \\\"details\\\": { ... } // Optional additional context\n }\n}\n```\n\n### Authentication & Authorization Errors\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `unauthorized` | 401 | Missing or invalid API key/token |\n| `invalid_api_key` | 401 | API key is invalid, expired, or revoked |\n| `forbidden` | 403 | Valid credentials but insufficient permissions |\n| `not_authenticated` | 401 | Authentication required for this operation |\n\n### Rate Limiting & Budget Errors\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `rate_limit_exceeded` | 429 | Request rate limit exceeded. Check `Retry-After` header. |\n| `budget_exceeded` | 402 | Budget limit exceeded for the configured period. Details include `limit_cents`, `current_spend_cents`, and `period`. |\n| `cache_required` | 503 | Budget enforcement requires cache to be configured |\n\n### Request Validation Errors\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `validation_error` | 400 | Request body validation failed |\n| `bad_request` | 400 | Malformed request |\n| `routing_error` | 400 | Model routing failed (invalid model string or provider not found) |\n| `not_found` | 404 | Requested resource not found |\n| `conflict` | 409 | Resource already exists or conflicts with existing state |\n\n### Provider & Gateway Errors\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `provider_error` | 502 | Upstream LLM provider returned an error |\n| `request_failed` | 502 | Failed to communicate with upstream provider |\n| `circuit_breaker_open` | 503 | Provider circuit breaker is open due to repeated failures |\n| `response_read_error` | 500 | Failed to read provider response |\n| `response_builder` | 500 | Failed to build response from provider data |\n| `internal_error` | 500 | Internal server error |\n\n### Guardrails Errors\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `guardrails_blocked` | 400 | Content blocked by guardrails policy. Response includes `violations` array. |\n| `guardrails_timeout` | 504 | Guardrails evaluation timed out |\n| `guardrails_provider_error` | 502 | Error communicating with guardrails provider |\n| `guardrails_auth_error` | 502 | Authentication failed with guardrails provider |\n| `guardrails_rate_limited` | 429 | Guardrails provider rate limit exceeded |\n| `guardrails_config_error` | 500 | Invalid guardrails configuration |\n| `guardrails_parse_error` | 400 | Failed to parse content for guardrails evaluation |\n\n### Admin API Errors\n\n| Code | HTTP Status | Description |\n|------|-------------|-------------|\n| `database_required` | 503 | Database not configured (required for admin operations) |\n| `services_required` | 503 | Required services not initialized |\n| `not_configured` | 503 | Required feature or service not configured |\n| `database_error` | 500 | Database operation failed |\n\n## Rate Limiting\n\nThe gateway implements multiple layers of rate limiting to protect against abuse and ensure fair usage.\n\n### Rate Limit Types\n\n| Type | Scope | Default | Description |\n|------|-------|---------|-------------|\n| **Requests per minute** | API Key | 60 | Maximum requests per minute per API key |\n| **Requests per day** | API Key | Unlimited | Optional daily request limit per API key |\n| **Tokens per minute** | API Key | 100,000 | Maximum tokens processed per minute |\n| **Tokens per day** | API Key | Unlimited | Optional daily token limit |\n| **Concurrent requests** | API Key | 10 | Maximum simultaneous in-flight requests |\n| **IP requests per minute** | IP Address | 120 | Rate limit for unauthenticated requests |\n\n### Rate Limit Headers\n\nAll API responses include rate limit information in HTTP headers.\n\n#### Request Rate Limit Headers\n\n| Header | Description | Example |\n|--------|-------------|---------|\n| `X-RateLimit-Limit` | Maximum requests allowed in the current window | `60` |\n| `X-RateLimit-Remaining` | Requests remaining in the current window | `45` |\n| `X-RateLimit-Reset` | Seconds until the rate limit window resets | `42` |\n\n#### Token Rate Limit Headers\n\n| Header | Description | Example |\n|--------|-------------|---------|\n| `X-TokenRateLimit-Limit` | Maximum tokens allowed per minute | `100000` |\n| `X-TokenRateLimit-Remaining` | Tokens remaining in the current minute | `85000` |\n| `X-TokenRateLimit-Used` | Tokens used in the current minute | `15000` |\n| `X-TokenRateLimit-Day-Limit` | Maximum tokens allowed per day (if configured) | `1000000` |\n| `X-TokenRateLimit-Day-Remaining` | Tokens remaining today (if configured) | `950000` |\n\n#### Rate Limit Exceeded Response\n\nWhen a rate limit is exceeded, the API returns HTTP 429 with:\n\n```json\n{\n \\\"error\\\": {\n \\\"code\\\": \\\"rate_limit_exceeded\\\",\n \\\"message\\\": \\\"Rate limit exceeded: 60 requests per minute\\\",\n \\\"details\\\": {\n \\\"limit\\\": 60,\n \\\"window\\\": \\\"minute\\\",\n \\\"retry_after_secs\\\": 42\n }\n }\n}\n```\n\nThe `Retry-After` header indicates seconds to wait before retrying:\n\n```\nHTTP/1.1 429 Too Many Requests\nRetry-After: 42\nX-RateLimit-Limit: 60\nX-RateLimit-Remaining: 0\nX-RateLimit-Reset: 42\n```\n\n### IP-Based Rate Limiting\n\nUnauthenticated requests (requests without a valid API key) are rate limited by IP address. This protects public endpoints like `/health` from abuse.\n\n- **Default:** 120 requests per minute per IP\n- **Client IP Detection:** Respects `X-Forwarded-For` and `X-Real-IP` headers when trusted proxies are configured\n- **Configuration:** Can be disabled or adjusted via `limits.rate_limits.ip_rate_limits` in config\n\n### Rate Limit Configuration\n\nRate limits are configured hierarchically:\n\n1. **Global defaults** (in `hadrian.toml`):\n```toml\n[limits.rate_limits]\nrequests_per_minute = 60\ntokens_per_minute = 100000\nconcurrent_requests = 10\n\n[limits.rate_limits.ip_rate_limits]\nenabled = true\nrequests_per_minute = 120\n```\n\n2. **Per-API key** limits can override global defaults (when creating API keys via Admin API)\n\n### Best Practices\n\n- **Implement exponential backoff**: When receiving 429 responses, wait the `Retry-After` duration before retrying\n- **Monitor rate limit headers**: Track `X-RateLimit-Remaining` to proactively throttle requests\n- **Use streaming for long responses**: Streaming responses don't hold connections during generation\n- **Batch requests when possible**: Combine multiple small requests into larger batches\n", "license": { "name": "Apache-2.0 OR MIT", "url": "https://github.com/ScriptSmith/hadrian/blob/main/LICENSE-APACHE" }, "version": "0.0.0-alpha.12" }, "servers": [ { "url": "/", "description": "Default server" } ], "paths": { "/.well-known/oauth-authorization-server": { "get": { "tags": [ "oauth" ], "summary": "Serve the OAuth 2.0 Authorization Server Metadata document.", "operationId": "oauth_authorization_server_metadata", "responses": { "200": { "description": "Authorization server metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthorizationServerMetadata" } } } }, "404": { "description": "OAuth PKCE flow disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/access-reviews/inventory": { "get": { "tags": [ "access-reviews" ], "summary": "Get access inventory for compliance reviews", "description": "Returns a comprehensive view of all users and their access rights across\norganizations and projects. This endpoint supports compliance requirements\nfor access reviews (SOC 2, ISO 27001).\n\nThe response includes:\n- User details (id, email, name, external_id)\n- Organization memberships with roles and grant dates\n- Project memberships with roles and grant dates\n- API key summary (active, revoked, expired counts)\n- Last activity timestamp\n- Summary statistics\n\nUse `format=csv` for CSV export suitable for auditors and spreadsheets.", "operationId": "access_review_inventory", "parameters": [ { "name": "org_id", "in": "query", "description": "Filter by organization ID", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of users to return (default: 100, max: 1000)", "required": false, "schema": { "type": "integer", "format": "int64", "default": 100, "maximum": 1000 } }, { "name": "offset", "in": "query", "description": "Offset for pagination", "required": false, "schema": { "type": "integer", "format": "int64", "default": 0 } }, { "name": "format", "in": "query", "description": "Export format (json or csv)", "required": false, "schema": { "oneOf": [ { "$ref": "#/components/schemas/ExportFormat" } ], "default": "json" } } ], "responses": { "200": { "description": "Access inventory (JSON or CSV based on format parameter)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AccessInventoryResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/access-reviews/stale": { "get": { "tags": [ "access-reviews" ], "summary": "Detect stale access across the system", "description": "Identifies users and API keys that haven't been active for a configurable\nnumber of days. This helps identify:\n- Users who haven't logged in or performed any actions\n- API keys that haven't been used\n- Users with access but no recorded activity\n\nThis endpoint supports compliance requirements for periodic access reviews\n(SOC 2, ISO 27001) by identifying potentially orphaned or unused access.\n\nUse `format=csv` for CSV export suitable for auditors and spreadsheets.", "operationId": "stale_access_detection", "parameters": [ { "name": "inactive_days", "in": "query", "description": "Number of days of inactivity to consider access stale (default: 90)", "required": false, "schema": { "type": "integer", "format": "int64", "default": 90, "maximum": 365, "minimum": 1 } }, { "name": "org_id", "in": "query", "description": "Filter by organization ID", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return (default: 100, max: 1000)", "required": false, "schema": { "type": "integer", "format": "int64", "default": 100, "maximum": 1000 } }, { "name": "format", "in": "query", "description": "Export format (json or csv)", "required": false, "schema": { "oneOf": [ { "$ref": "#/components/schemas/ExportFormat" } ], "default": "json" } } ], "responses": { "200": { "description": "Stale access report (JSON or CSV based on format parameter)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StaleAccessResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/api-keys": { "post": { "tags": [ "api-keys" ], "summary": "Create an API key", "description": "Creates a new API key scoped to an organization, project, or user. The raw API key value\nis returned only once in this response and cannot be retrieved later. Store it securely.", "operationId": "api_key_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateApiKey" }, "examples": { "Organization key": { "summary": "Create an org-scoped API key", "value": { "name": "Production API Key", "owner": { "type": "organization", "org_id": "550e8400-e29b-41d4-a716-446655440000" } } }, "Project key with budget": { "summary": "Create a project-scoped key with budget limits", "value": { "name": "Dev Team Key", "owner": { "type": "project", "project_id": "123e4567-e89b-12d3-a456-426614174000" }, "budget_limit_cents": 10000, "budget_period": "monthly" } }, "Service account key": { "summary": "Create a service account-scoped API key", "value": { "name": "CI/CD Pipeline Key", "owner": { "type": "service_account", "service_account_id": "8d0e7891-3456-78ef-9012-345678901234" } } }, "User key with expiration": { "summary": "Create a user-scoped key with expiration", "value": { "name": "Personal Key", "owner": { "type": "user", "user_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7" }, "expires_at": "2025-12-31T23:59:59Z" } } } } }, "required": true }, "responses": { "201": { "description": "API key created successfully. Store the key value securely - it won't be shown again.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatedApiKey" }, "example": { "api_key": { "id": "550e8400-e29b-41d4-a716-446655440001", "name": "Production API Key", "key_prefix": "gw_live_abc", "owner": { "type": "organization", "org_id": "550e8400-e29b-41d4-a716-446655440000" }, "budget_limit": null, "budget_period": null, "created_at": "2025-01-15T10:30:00Z", "expires_at": null, "revoked_at": null }, "key": "gw_live_abc123def456ghi789jkl012mno345pqr678" } } } }, "404": { "description": "Owner (organization, project, or user) not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": { "code": "not_found", "message": "Organization '550e8400-e29b-41d4-a716-446655440000' not found" } } } } } } } }, "/admin/v1/api-keys/{key_id}": { "delete": { "tags": [ "api-keys" ], "summary": "Revoke an API key", "operationId": "api_key_revoke", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "API key revoked" }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/api-keys/{key_id}/rotate": { "post": { "tags": [ "api-keys" ], "summary": "Rotate an API key", "description": "Creates a new API key with the same settings as the old key and sets a grace period\non the old key. During the grace period, both keys are valid. After the grace period\nexpires, only the new key works.\n\nThe raw API key value for the new key is returned only once in this response.", "operationId": "api_key_rotate", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID to rotate", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RotateApiKeyRequest" }, "examples": { "Custom grace period": { "summary": "Rotate with 1-hour grace period", "value": { "grace_period_seconds": 3600 } }, "Default grace period": { "summary": "Rotate with default 24-hour grace period", "value": {} } } } }, "required": true }, "responses": { "201": { "description": "API key rotated successfully. Store the new key value securely - it won't be shown again.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatedApiKey" }, "example": { "api_key": { "id": "550e8400-e29b-41d4-a716-446655440002", "name": "Production API Key (rotated)", "key_prefix": "gw_live_xyz", "owner": { "type": "organization", "org_id": "550e8400-e29b-41d4-a716-446655440000" }, "rotated_from_key_id": "550e8400-e29b-41d4-a716-446655440001", "created_at": "2025-01-15T10:30:00Z" }, "key": "gw_live_xyz123abc456def789ghi012jkl345mno678" } } } }, "400": { "description": "Invalid grace period", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": { "code": "validation_error", "message": "Grace period cannot exceed 604800 seconds (7 days)" } } } } }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": { "code": "not_found", "message": "API key not found" } } } } }, "409": { "description": "API key cannot be rotated (already revoked or being rotated)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": { "code": "conflict", "message": "API key is already being rotated" } } } } } } } }, "/admin/v1/api-keys/{key_id}/usage": { "get": { "tags": [ "usage" ], "summary": "Get usage summary for an API key", "operationId": "usage_get_summary", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsageSummaryResponse" } } } }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/api-keys/{key_id}/usage/by-date": { "get": { "tags": [ "usage" ], "summary": "Get usage by date for an API key", "operationId": "usage_get_by_date", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailySpendResponse" } } } } }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/api-keys/{key_id}/usage/by-date-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and model for an API key", "operationId": "usage_get_by_date_model", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyModelSpendResponse" } } } } } } } }, "/admin/v1/api-keys/{key_id}/usage/by-date-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and pricing source for an API key", "operationId": "usage_get_by_date_pricing_source", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyPricingSourceSpendResponse" } } } } } } } }, "/admin/v1/api-keys/{key_id}/usage/by-date-provider": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and provider for an API key", "operationId": "usage_get_by_date_provider", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyProviderSpendResponse" } } } } } } } }, "/admin/v1/api-keys/{key_id}/usage/by-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by model for an API key", "operationId": "usage_get_by_model", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ModelSpendResponse" } } } } }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/api-keys/{key_id}/usage/by-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get usage by pricing source for an API key", "operationId": "usage_get_by_pricing_source", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PricingSourceSpendResponse" } } } } } } } }, "/admin/v1/api-keys/{key_id}/usage/by-provider": { "get": { "tags": [ "usage" ], "summary": "Get usage by provider for an API key", "operationId": "usage_get_by_provider", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProviderSpendResponse" } } } } }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/api-keys/{key_id}/usage/by-referer": { "get": { "tags": [ "usage" ], "summary": "Get usage by referer for an API key", "operationId": "usage_get_by_referer", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by HTTP referer", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/RefererSpendResponse" } } } } }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/api-keys/{key_id}/usage/forecast": { "get": { "tags": [ "usage" ], "summary": "Get cost forecast for an API key", "description": "Uses historical usage data to predict when the budget will be exhausted.\nReturns average daily spend, projected exhaustion date, and confidence intervals.", "operationId": "usage_get_forecast", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "lookback_days", "in": "query", "description": "Number of days of historical data to use (default: 30)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int32" } }, { "name": "forecast_days", "in": "query", "description": "Number of days to forecast ahead (default: 7)", "required": false, "schema": { "type": [ "integer", "null" ], "minimum": 0 } } ], "responses": { "200": { "description": "Cost forecast", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CostForecastResponse" } } } }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/audit-logs": { "get": { "tags": [ "audit-logs" ], "summary": "List audit logs", "operationId": "audit_log_list", "parameters": [ { "name": "actor_type", "in": "query", "description": "Filter by actor type", "required": false, "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AuditActorType" } ] } }, { "name": "actor_id", "in": "query", "description": "Filter by actor ID", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "action", "in": "query", "description": "Filter by action (e.g., \"api_key.create\")", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "resource_type", "in": "query", "description": "Filter by resource type (e.g., \"api_key\")", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "resource_id", "in": "query", "description": "Filter by resource ID", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "org_id", "in": "query", "description": "Filter by organization ID", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "project_id", "in": "query", "description": "Filter by project ID", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "from", "in": "query", "description": "Start of time range (inclusive)", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "to", "in": "query", "description": "End of time range (exclusive)", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for pagination (cursor-based pagination)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction (forward or backward). Only used with cursor.", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "List of audit log entries", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuditLogListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/audit-logs/{id}": { "get": { "tags": [ "audit-logs" ], "summary": "Get an audit log entry by ID", "operationId": "audit_log_get", "parameters": [ { "name": "id", "in": "path", "description": "Audit log entry ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Audit log entry found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuditLog" } } } }, "404": { "description": "Audit log entry not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/conversations": { "post": { "tags": [ "conversations" ], "summary": "Create a new conversation", "operationId": "conversation_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateConversation" } } }, "required": true }, "responses": { "201": { "description": "Conversation created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Conversation" } } } }, "404": { "description": "Owner not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/conversations/{id}": { "get": { "tags": [ "conversations" ], "summary": "Get a conversation by ID", "operationId": "conversation_get", "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Conversation found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Conversation" } } } }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "conversations" ], "summary": "Delete a conversation", "operationId": "conversation_delete", "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Conversation deleted" }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "conversations" ], "summary": "Update a conversation", "description": "Can also be used to move a conversation to a different project or user by providing the `owner` field.", "operationId": "conversation_update", "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateConversation" } } }, "required": true }, "responses": { "200": { "description": "Conversation updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Conversation" } } } }, "404": { "description": "Conversation or new owner not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/conversations/{id}/messages": { "post": { "tags": [ "conversations" ], "summary": "Append messages to a conversation", "operationId": "conversation_append_messages", "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AppendMessages" } } }, "required": true }, "responses": { "200": { "description": "Messages appended, returns all messages", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Message" } } } } }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/conversations/{id}/pin": { "put": { "tags": [ "conversations" ], "summary": "Set pin order for a conversation", "description": "Set `pin_order` to a number to pin the conversation (0 = first, higher = lower in list).\nSet `pin_order` to null to unpin the conversation.", "operationId": "conversation_set_pin", "parameters": [ { "name": "id", "in": "path", "description": "Conversation ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetPinOrder" } } }, "required": true }, "responses": { "200": { "description": "Pin order updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Conversation" } } } }, "404": { "description": "Conversation not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/dlq": { "get": { "tags": [ "dlq" ], "summary": "List DLQ entries.", "operationId": "dlq_list", "parameters": [ { "name": "entry_type", "in": "query", "description": "Filter by entry type (e.g., \"usage_log\").", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "limit", "in": "query", "description": "Maximum number of entries to return (default: 100).", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "max_retries", "in": "query", "description": "Only return entries with fewer than this many retries.", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int32" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "List of DLQ entries", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DlqListResponse" } } } }, "400": { "description": "DLQ not configured or invalid cursor", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "dlq" ], "summary": "Purge all DLQ entries.", "operationId": "dlq_purge", "responses": { "200": { "description": "Purge result", "content": { "application/json": { "schema": {} } } }, "400": { "description": "DLQ not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/dlq/prune": { "post": { "tags": [ "dlq" ], "operationId": "dlq_prune", "parameters": [ { "name": "older_than_secs", "in": "query", "description": "Prune entries older than this many seconds (default: TTL from config).", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64", "minimum": 0 } } ], "responses": { "200": { "description": "Prune result", "content": { "application/json": { "schema": {} } } }, "400": { "description": "DLQ not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/dlq/stats": { "get": { "tags": [ "dlq" ], "summary": "Get DLQ statistics.", "operationId": "dlq_stats", "responses": { "200": { "description": "DLQ statistics", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DlqStatsResponse" } } } }, "400": { "description": "DLQ not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/dlq/{id}": { "get": { "tags": [ "dlq" ], "summary": "Get a specific DLQ entry by ID.", "operationId": "dlq_get", "parameters": [ { "name": "id", "in": "path", "description": "DLQ entry ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "DLQ entry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DlqEntryResponse" } } } }, "400": { "description": "DLQ not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Entry not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "dlq" ], "summary": "Delete a DLQ entry.", "operationId": "dlq_delete", "parameters": [ { "name": "id", "in": "path", "description": "DLQ entry ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Entry deleted" }, "400": { "description": "DLQ not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Entry not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/dlq/{id}/retry": { "post": { "tags": [ "dlq" ], "summary": "Retry a specific DLQ entry.", "operationId": "dlq_retry", "parameters": [ { "name": "id", "in": "path", "description": "DLQ entry ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Retry result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DlqRetryResponse" } } } }, "400": { "description": "DLQ not configured or invalid entry", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Entry not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/dynamic-providers": { "post": { "tags": [ "dynamic-providers" ], "summary": "Create a dynamic provider", "operationId": "dynamic_provider_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateDynamicProvider" } } }, "required": true }, "responses": { "201": { "description": "Dynamic provider created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicProviderResponse" } } } }, "404": { "description": "Owner not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/dynamic-providers/test-credentials": { "post": { "tags": [ "dynamic-providers" ], "summary": "Test credentials before creating a dynamic provider", "description": "Accepts the same body as the create endpoint but does not persist anything.\nUseful for validating API keys and endpoints before committing.", "operationId": "dynamic_provider_test_credentials", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateDynamicProvider" } } }, "required": true }, "responses": { "200": { "description": "Connectivity test result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConnectivityTestResponse" } } } }, "422": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/dynamic-providers/{id}": { "get": { "tags": [ "dynamic-providers" ], "summary": "Get a dynamic provider by ID", "operationId": "dynamic_provider_get", "parameters": [ { "name": "id", "in": "path", "description": "Dynamic provider ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Dynamic provider found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicProviderResponse" } } } }, "404": { "description": "Dynamic provider not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "dynamic-providers" ], "summary": "Delete a dynamic provider", "operationId": "dynamic_provider_delete", "parameters": [ { "name": "id", "in": "path", "description": "Dynamic provider ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Dynamic provider deleted" }, "404": { "description": "Dynamic provider not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "dynamic-providers" ], "summary": "Update a dynamic provider", "operationId": "dynamic_provider_update", "parameters": [ { "name": "id", "in": "path", "description": "Dynamic provider ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateDynamicProvider" } } }, "required": true }, "responses": { "200": { "description": "Dynamic provider updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicProviderResponse" } } } }, "404": { "description": "Dynamic provider not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/dynamic-providers/{id}/test": { "post": { "tags": [ "dynamic-providers" ], "summary": "Test connectivity for an existing dynamic provider", "description": "Sends a lightweight request to the provider to verify the API key and endpoint are working.", "operationId": "dynamic_provider_test", "parameters": [ { "name": "id", "in": "path", "description": "Dynamic provider ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Connectivity test result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConnectivityTestResponse" } } } }, "404": { "description": "Provider not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me": { "delete": { "tags": [ "me" ], "summary": "Delete current user and all associated data (GDPR Article 17 - Right to Erasure)", "description": "Permanently deletes the authenticated user and all associated data including:\n- User record\n- Organization and project memberships\n- API keys owned by the user\n- Conversations owned by the user\n- Dynamic providers owned by the user\n- Usage records for user's API keys\n\nThis endpoint allows users to delete their own account without admin permissions.\nThe user is identified from the authenticated session.\n\n**Warning:** This operation is irreversible.", "operationId": "me_delete", "responses": { "200": { "description": "User deleted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserDeletionResponse" } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/api-keys": { "get": { "tags": [ "me" ], "summary": "List current user's API keys", "operationId": "me_api_keys_list", "parameters": [ { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of user's API keys", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKeyListResponse" } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "me" ], "summary": "Create an API key for the current user", "operationId": "me_api_keys_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSelfServiceApiKey" } } }, "required": true }, "responses": { "201": { "description": "API key created. Store the key value securely - it won't be shown again.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatedApiKey" } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "422": { "description": "API key limit exceeded or validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/api-keys/{key_id}": { "get": { "tags": [ "me" ], "summary": "Get an API key by ID (current user only)", "operationId": "me_api_keys_get", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "API key found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKey" } } } }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "me" ], "summary": "Revoke an API key (current user only)", "operationId": "me_api_keys_revoke", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "API key revoked" }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/api-keys/{key_id}/rotate": { "post": { "tags": [ "me" ], "summary": "Rotate an API key (current user only)", "description": "Creates a new API key with the same settings as the old key and sets a grace period\non the old key. During the grace period, both keys are valid.", "operationId": "me_api_keys_rotate", "parameters": [ { "name": "key_id", "in": "path", "description": "API key ID to rotate", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RotateApiKeyRequest" } } }, "required": true }, "responses": { "201": { "description": "API key rotated. Store the new key value securely.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatedApiKey" } } } }, "400": { "description": "Invalid grace period", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "API key not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "API key cannot be rotated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/built-in-providers": { "get": { "tags": [ "me" ], "summary": "List built-in providers from the gateway configuration", "operationId": "me_built_in_providers_list", "responses": { "200": { "description": "List of built-in providers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BuiltInProvidersResponse" } } } } } } }, "/admin/v1/me/eligible-owners": { "get": { "tags": [ "me" ], "summary": "List the owners the current user can plausibly issue an API key for.", "description": "This is a hint for the OAuth consent UI; the actual create-permission\ncheck still runs server-side at consent time, so an owner appearing\nhere doesn't guarantee the create will succeed if RBAC denies it.", "operationId": "me_eligible_owners", "responses": { "200": { "description": "Owners the user can pick from", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EligibleOwnersResponse" } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/export": { "get": { "tags": [ "me" ], "summary": "Export current user's data (GDPR Article 15 - Right of Access)", "description": "Exports all personal data associated with the authenticated user including:\n- User profile\n- Organization and project memberships\n- API keys (excluding sensitive hash)\n- Conversations\n- Usage summary\n- Audit logs where user was the actor\n\nThis endpoint allows users to export their own data without admin permissions.\nThe user is identified from the authenticated session.", "operationId": "me_export", "responses": { "200": { "description": "User data export", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserDataExport" } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/providers": { "get": { "tags": [ "me" ], "summary": "List current user's dynamic providers", "operationId": "me_providers_list", "parameters": [ { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of user's dynamic providers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SelfServiceProviderListResponse" } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "me" ], "summary": "Create a dynamic provider for the current user", "operationId": "me_providers_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSelfServiceProvider" } } }, "required": true }, "responses": { "201": { "description": "Dynamic provider created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicProviderResponse" } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Provider with this name already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "422": { "description": "Provider limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/providers/test-credentials": { "post": { "tags": [ "me" ], "summary": "Test credentials before creating a provider", "description": "Accepts the same body as the create endpoint but does not persist anything.\nUseful for validating API keys and endpoints before committing.", "operationId": "me_providers_test_credentials", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSelfServiceProvider" } } }, "required": true }, "responses": { "200": { "description": "Connectivity test result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConnectivityTestResponse" } } } }, "422": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/providers/{id}": { "get": { "tags": [ "me" ], "summary": "Get a dynamic provider by ID (current user only)", "operationId": "me_providers_get", "parameters": [ { "name": "id", "in": "path", "description": "Dynamic provider ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Dynamic provider found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicProviderResponse" } } } }, "404": { "description": "Provider not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "me" ], "summary": "Delete a dynamic provider (current user only)", "operationId": "me_providers_delete", "parameters": [ { "name": "id", "in": "path", "description": "Dynamic provider ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Provider deleted" }, "404": { "description": "Provider not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "me" ], "summary": "Update a dynamic provider (current user only)", "operationId": "me_providers_update", "parameters": [ { "name": "id", "in": "path", "description": "Dynamic provider ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateDynamicProvider" } } }, "required": true }, "responses": { "200": { "description": "Dynamic provider updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicProviderResponse" } } } }, "404": { "description": "Provider not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/providers/{id}/test": { "post": { "tags": [ "me" ], "summary": "Test connectivity for a dynamic provider (current user only)", "description": "Sends a lightweight request to the provider to verify the API key and endpoint are working.", "operationId": "me_providers_test", "parameters": [ { "name": "id", "in": "path", "description": "Dynamic provider ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Connectivity test result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConnectivityTestResponse" } } } }, "404": { "description": "Provider not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/sessions": { "get": { "tags": [ "me" ], "summary": "List current user's active sessions.", "description": "Returns an empty list if enhanced session management is not enabled.\nThe `enhanced_enabled` field indicates whether session tracking is active.", "operationId": "me_sessions_list", "responses": { "200": { "description": "List of current user's sessions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SessionListResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/sessions/{session_id}": { "delete": { "tags": [ "me" ], "summary": "Revoke a specific session belonging to the current user.", "description": "Returns success even if the session doesn't exist (idempotent).\nReturns 400 if the session belongs to a different user.", "operationId": "me_sessions_delete_one", "parameters": [ { "name": "session_id", "in": "path", "description": "Session ID to revoke", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Session revoked", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SessionsRevokedResponse" } } } }, "400": { "description": "Session does not belong to current user", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/usage": { "get": { "tags": [ "me" ], "summary": "Get current user's usage summary", "description": "Returns usage data for the authenticated user. Does not require admin role.", "operationId": "me_usage_summary", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsageSummaryResponse" } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/usage/by-date": { "get": { "tags": [ "me" ], "summary": "Get current user's usage by date", "operationId": "me_usage_by_date", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailySpendResponse" } } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/usage/by-date-model": { "get": { "tags": [ "me" ], "summary": "Get current user's usage by date and model", "operationId": "me_usage_by_date_model", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyModelSpendResponse" } } } } } } } }, "/admin/v1/me/usage/by-date-pricing-source": { "get": { "tags": [ "me" ], "summary": "Get current user's usage by date and pricing source", "operationId": "me_usage_by_date_pricing_source", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyPricingSourceSpendResponse" } } } } } } } }, "/admin/v1/me/usage/by-date-provider": { "get": { "tags": [ "me" ], "summary": "Get current user's usage by date and provider", "operationId": "me_usage_by_date_provider", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyProviderSpendResponse" } } } } } } } }, "/admin/v1/me/usage/by-model": { "get": { "tags": [ "me" ], "summary": "Get current user's usage by model", "operationId": "me_usage_by_model", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ModelSpendResponse" } } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/usage/by-pricing-source": { "get": { "tags": [ "me" ], "summary": "Get current user's usage by pricing source", "operationId": "me_usage_by_pricing_source", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PricingSourceSpendResponse" } } } } } } } }, "/admin/v1/me/usage/by-provider": { "get": { "tags": [ "me" ], "summary": "Get current user's usage by provider", "operationId": "me_usage_by_provider", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProviderSpendResponse" } } } } }, "401": { "description": "User not identified from session", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/me/usage/logs": { "get": { "tags": [ "me" ], "summary": "List current user's usage logs", "operationId": "me_usage_log_list", "parameters": [ { "name": "org_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "user_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "project_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "team_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "api_key_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "service_account_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "model", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "provider", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "provider_source", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "from", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "to", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "limit", "in": "query", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "List of usage log records", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsageLogListResponse" } } } } } } }, "/admin/v1/me/usage/logs/export": { "get": { "tags": [ "me" ], "summary": "Export current user's usage logs", "operationId": "me_usage_log_export", "parameters": [ { "name": "org_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "user_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "project_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "team_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "api_key_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "service_account_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "model", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "provider", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "provider_source", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "from", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "to", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "format", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/UsageLogExportFormat" } } ], "responses": { "200": { "description": "Exported usage logs", "content": { "application/x-ndjson": {} } } } } }, "/admin/v1/model-pricing": { "get": { "tags": [ "model-pricing" ], "summary": "List global model pricing", "operationId": "model_pricing_list_global", "parameters": [ { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of global model pricing", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelPricingListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "model-pricing" ], "summary": "Create a new model pricing entry", "operationId": "model_pricing_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateModelPricing" } } }, "required": true }, "responses": { "201": { "description": "Model pricing created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DbModelPricing" } } } }, "409": { "description": "Conflict (pricing already exists)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/model-pricing/bulk": { "post": { "tags": [ "model-pricing" ], "summary": "Bulk upsert model pricing entries", "operationId": "model_pricing_bulk_upsert", "requestBody": { "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CreateModelPricing" } } } }, "required": true }, "responses": { "200": { "description": "Bulk upsert completed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BulkUpsertResponse" } } } } } } }, "/admin/v1/model-pricing/provider/{provider}": { "get": { "tags": [ "model-pricing" ], "summary": "List all pricing for a specific provider (across all scopes)", "operationId": "model_pricing_list_by_provider", "parameters": [ { "name": "provider", "in": "path", "description": "Provider name", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of pricing for provider", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelPricingListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/model-pricing/upsert": { "post": { "tags": [ "model-pricing" ], "summary": "Upsert model pricing (create or update based on owner/provider/model)", "operationId": "model_pricing_upsert", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateModelPricing" } } }, "required": true }, "responses": { "200": { "description": "Model pricing upserted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DbModelPricing" } } } } } } }, "/admin/v1/model-pricing/{id}": { "get": { "tags": [ "model-pricing" ], "summary": "Get a model pricing entry by ID", "operationId": "model_pricing_get", "parameters": [ { "name": "id", "in": "path", "description": "Model pricing ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Model pricing found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DbModelPricing" } } } }, "404": { "description": "Model pricing not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "model-pricing" ], "summary": "Delete a model pricing entry", "operationId": "model_pricing_delete", "parameters": [ { "name": "id", "in": "path", "description": "Model pricing ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Model pricing deleted" }, "404": { "description": "Model pricing not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "model-pricing" ], "summary": "Update a model pricing entry", "operationId": "model_pricing_update", "parameters": [ { "name": "id", "in": "path", "description": "Model pricing ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateModelPricing" } } }, "required": true }, "responses": { "200": { "description": "Model pricing updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DbModelPricing" } } } }, "404": { "description": "Model pricing not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/oauth/authorize": { "post": { "tags": [ "oauth" ], "summary": "Issue an authorization code after explicit user consent.", "description": "The browser calls this endpoint from the consent page when the user clicks\n\"Allow\". The endpoint:\n\n1. Validates the requested scopes and key name shape (mirroring the\n self-service API key endpoint), so we reject obvious mistakes before\n issuing the code.\n2. Validates the callback URL scheme and host against\n `auth.oauth_pkce.allowed_domains` / `denied_domains`.\n3. Persists a single-use authorization code bound to the current user\n and the supplied PKCE challenge.\n4. Returns the redirect URL the page should send the browser to.", "operationId": "oauth_authorize", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAuthorizationCode" } } }, "required": true }, "responses": { "201": { "description": "Authorization code issued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthorizationCodeResponse" } } } }, "400": { "description": "Invalid PKCE request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Callback domain not permitted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "OAuth PKCE flow disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/oauth/preflight": { "get": { "tags": [ "oauth" ], "summary": "Validate a `callback_url` against the deployment's OAuth PKCE policy\nwithout issuing a code. The consent UI calls this on mount and refuses\nto render if the URL is rejected — closing the gap where a \"Deny\"\nclick could otherwise redirect to a host the operator denied.", "operationId": "oauth_preflight", "parameters": [ { "name": "callback_url", "in": "query", "description": "The callback URL the external app intends to use.", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Callback URL passes policy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PreflightResponse" } } } }, "400": { "description": "Invalid URL or scheme", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Callback host denied by policy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "OAuth PKCE flow disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations": { "get": { "tags": [ "organizations" ], "summary": "List all organizations", "operationId": "organization_list", "parameters": [ { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of organizations", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrganizationListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "organizations" ], "summary": "Create an organization", "operationId": "organization_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateOrganization" } } }, "required": true }, "responses": { "201": { "description": "Organization created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Organization" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict (slug already exists)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/access-report": { "get": { "tags": [ "access-reviews" ], "summary": "Get access report for a specific organization", "description": "Returns a comprehensive access report for the specified organization including:\n- All org members with their roles and project access\n- All API keys scoped to the organization or its projects\n- Recent access grant history from audit logs\n- Summary statistics\n\nUse `format=csv` for CSV export suitable for auditors and spreadsheets.", "operationId": "org_access_report", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "format", "in": "query", "description": "Export format (json or csv)", "required": false, "schema": { "oneOf": [ { "$ref": "#/components/schemas/ExportFormat" } ], "default": "json" } } ], "responses": { "200": { "description": "Organization access report (JSON or CSV based on format parameter)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgAccessReportResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/api-keys": { "get": { "tags": [ "api-keys" ], "summary": "List API keys by organization", "operationId": "api_key_list_by_org", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of API keys", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKeyListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/dynamic-providers": { "get": { "tags": [ "dynamic-providers" ], "summary": "List dynamic providers by organization", "operationId": "dynamic_provider_list_by_org", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of dynamic providers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicProviderListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/members": { "get": { "tags": [ "users" ], "summary": "List organization members", "operationId": "org_member_list", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of organization members", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "users" ], "summary": "Add a member to an organization", "operationId": "org_member_add", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddMemberRequest" } } }, "required": true }, "responses": { "201": { "description": "Member added" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or user not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/members/{user_id}": { "delete": { "tags": [ "users" ], "summary": "Remove a member from an organization", "operationId": "org_member_remove", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Member removed" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/model-pricing": { "get": { "tags": [ "model-pricing" ], "summary": "List model pricing for an organization", "operationId": "model_pricing_list_by_org", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of organization model pricing", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelPricingListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects": { "get": { "tags": [ "projects" ], "summary": "List projects in an organization", "operationId": "project_list", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of projects", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProjectListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "projects" ], "summary": "Create a project in an organization", "operationId": "project_create", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateProject" } } }, "required": true }, "responses": { "201": { "description": "Project created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Project" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict (slug already exists)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}": { "get": { "tags": [ "projects" ], "summary": "Get a project by slug", "operationId": "project_get", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Project found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Project" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "projects" ], "summary": "Delete a project", "operationId": "project_delete", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Project deleted" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "projects" ], "summary": "Update a project", "operationId": "project_update", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateProject" } } }, "required": true }, "responses": { "200": { "description": "Project updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Project" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/api-keys": { "get": { "tags": [ "api-keys" ], "summary": "List API keys by project", "operationId": "api_key_list_by_project", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of API keys", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKeyListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/conversations": { "get": { "tags": [ "conversations" ], "summary": "List conversations by project", "operationId": "conversation_list_by_project", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of conversations", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/dynamic-providers": { "get": { "tags": [ "dynamic-providers" ], "summary": "List dynamic providers by project", "operationId": "dynamic_provider_list_by_project", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of dynamic providers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicProviderListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/members": { "get": { "tags": [ "users" ], "summary": "List project members", "operationId": "project_member_list", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of project members", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "users" ], "summary": "Add a member to a project", "operationId": "project_member_add", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddMemberRequest" } } }, "required": true }, "responses": { "201": { "description": "Member added" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization, project, or user not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/members/{user_id}": { "delete": { "tags": [ "users" ], "summary": "Remove a member from a project", "operationId": "project_member_remove", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Member removed" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/model-pricing": { "get": { "tags": [ "model-pricing" ], "summary": "List model pricing for a project", "operationId": "model_pricing_list_by_project", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of project model pricing", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelPricingListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/skills": { "get": { "tags": [ "skills" ], "summary": "List skills by project.", "operationId": "skill_list_by_project", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of skills", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SkillListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/templates": { "get": { "tags": [ "templates" ], "summary": "List templates by project", "operationId": "template_list_by_project", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of templates", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TemplateListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage": { "get": { "tags": [ "usage" ], "summary": "Get usage summary for a project", "operationId": "usage_get_project_summary", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsageSummaryResponse" } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage/by-date": { "get": { "tags": [ "usage" ], "summary": "Get usage by date for a project", "operationId": "usage_get_project_by_date", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailySpendResponse" } } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage/by-date-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and model for a project", "operationId": "usage_get_project_by_date_model", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyModelSpendResponse" } } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage/by-date-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and pricing source for a project", "operationId": "usage_get_project_by_date_pricing_source", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyPricingSourceSpendResponse" } } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage/by-date-provider": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and provider for a project", "operationId": "usage_get_project_by_date_provider", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyProviderSpendResponse" } } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage/by-date-user": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and user for a project", "operationId": "usage_get_project_by_date_user", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyUserSpendResponse" } } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage/by-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by model for a project", "operationId": "usage_get_project_by_model", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ModelSpendResponse" } } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage/by-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get usage by pricing source for a project", "operationId": "usage_get_project_by_pricing_source", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PricingSourceSpendResponse" } } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage/by-provider": { "get": { "tags": [ "usage" ], "summary": "Get usage by provider for a project", "operationId": "usage_get_project_by_provider", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProviderSpendResponse" } } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage/by-user": { "get": { "tags": [ "usage" ], "summary": "Get usage by user for a project", "operationId": "usage_get_project_by_user", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserSpendResponse" } } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/projects/{project_slug}/usage/forecast": { "get": { "tags": [ "usage" ], "summary": "Get cost forecast for a project", "description": "Uses historical usage data across all API keys in the project to predict future spending.\nReturns average daily spend, confidence intervals, and time series forecasts.", "operationId": "usage_get_project_forecast", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "project_slug", "in": "path", "description": "Project slug", "required": true, "schema": { "type": "string" } }, { "name": "lookback_days", "in": "query", "description": "Number of days of historical data to use (default: 30)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int32" } }, { "name": "forecast_days", "in": "query", "description": "Number of days to forecast ahead (default: 7)", "required": false, "schema": { "type": [ "integer", "null" ], "minimum": 0 } } ], "responses": { "200": { "description": "Cost forecast", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CostForecastResponse" } } } }, "404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/rbac-policies": { "get": { "tags": [ "rbac-policies" ], "summary": "List RBAC policies for an organization", "operationId": "org_rbac_policy_list", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of RBAC policies", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgRbacPolicyListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "rbac-policies" ], "summary": "Create a new RBAC policy for an organization", "operationId": "org_rbac_policy_create", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateOrgRbacPolicy" } } }, "required": true }, "responses": { "201": { "description": "RBAC policy created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgRbacPolicy" } } } }, "400": { "description": "Invalid CEL expression", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Policy with same name already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/rbac-policies/simulate": { "post": { "tags": [ "rbac-policies" ], "summary": "Simulate policy evaluation for an organization", "description": "Tests what decision would be made for a given subject and context.\nEvaluates both system policies (from config) and organization policies (from database),\nmatching the runtime authorization flow.\n\n## Evaluation Order\n\n1. Check if RBAC is disabled → return allow with `rbac_enabled: false`\n2. Evaluate system policies (from config file) first\n3. If a system policy matches → return that decision\n4. Evaluate organization policies (from database)\n5. If an org policy matches → return that decision\n6. No policy matched → apply configured `default_effect`", "operationId": "org_rbac_policy_simulate", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SimulatePolicyRequest" } } }, "required": true }, "responses": { "200": { "description": "Simulation result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SimulatePolicyResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/rbac-policies/{policy_id}": { "get": { "tags": [ "rbac-policies" ], "summary": "Get an RBAC policy by ID", "operationId": "org_rbac_policy_get", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "description": "Policy ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "RBAC policy found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgRbacPolicy" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or policy not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "rbac-policies" ], "summary": "Delete an RBAC policy", "operationId": "org_rbac_policy_delete", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "description": "Policy ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "RBAC policy deleted" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or policy not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "rbac-policies" ], "summary": "Update an RBAC policy", "operationId": "org_rbac_policy_update", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "description": "Policy ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateOrgRbacPolicy" } } }, "required": true }, "responses": { "200": { "description": "RBAC policy updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgRbacPolicy" } } } }, "400": { "description": "Invalid CEL expression", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or policy not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/rbac-policies/{policy_id}/rollback": { "post": { "tags": [ "rbac-policies" ], "summary": "Rollback an RBAC policy to a previous version", "operationId": "org_rbac_policy_rollback", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "description": "Policy ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RollbackOrgRbacPolicy" } } }, "required": true }, "responses": { "200": { "description": "Policy rolled back", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgRbacPolicy" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization, policy, or version not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/rbac-policies/{policy_id}/versions": { "get": { "tags": [ "rbac-policies" ], "summary": "List version history for an RBAC policy", "operationId": "org_rbac_policy_list_versions", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "policy_id", "in": "path", "description": "Policy ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of policy versions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgRbacPolicyVersionListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or policy not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/scim-config": { "get": { "tags": [ "scim" ], "summary": "Get the SCIM configuration for an organization", "operationId": "org_scim_config_get", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SCIM config found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgScimConfig" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or SCIM config not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "scim" ], "summary": "Create a new SCIM configuration for an organization", "description": "Each organization can have at most one SCIM configuration. Creating a config\nfor an organization that already has one will result in a 409 Conflict error.\n\nThe response includes the SCIM bearer token which is only shown once.\nStore it securely - it cannot be retrieved again.", "operationId": "org_scim_config_create", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateOrgScimConfig" } } }, "required": true }, "responses": { "201": { "description": "SCIM config created with bearer token", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatedOrgScimConfig" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Organization already has a SCIM config", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "scim" ], "summary": "Delete the SCIM configuration for an organization", "operationId": "org_scim_config_delete", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SCIM config deleted" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or SCIM config not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "scim" ], "summary": "Update the SCIM configuration for an organization", "operationId": "org_scim_config_update", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateOrgScimConfig" } } }, "required": true }, "responses": { "200": { "description": "SCIM config updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgScimConfig" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or SCIM config not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/scim-config/rotate-token": { "post": { "tags": [ "scim" ], "summary": "Rotate the SCIM bearer token for an organization", "description": "Generates a new bearer token and invalidates the old one immediately.\nThe new token is returned only once - store it securely.", "operationId": "org_scim_config_rotate_token", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Token rotated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatedOrgScimConfig" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or SCIM config not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/service-accounts": { "get": { "tags": [ "service_accounts" ], "summary": "List service accounts in an organization", "operationId": "service_account_list", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of service accounts", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ServiceAccountListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "service_accounts" ], "summary": "Create a service account in an organization", "operationId": "service_account_create", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateServiceAccount" } } }, "required": true }, "responses": { "201": { "description": "Service account created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ServiceAccount" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict (slug already exists)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/service-accounts/{sa_slug}": { "get": { "tags": [ "service_accounts" ], "summary": "Get a service account by slug", "operationId": "service_account_get", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "sa_slug", "in": "path", "description": "Service account slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Service account found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ServiceAccount" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or service account not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "service_accounts" ], "summary": "Delete a service account", "operationId": "service_account_delete", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "sa_slug", "in": "path", "description": "Service account slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Service account deleted" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or service account not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "service_accounts" ], "summary": "Update a service account", "operationId": "service_account_update", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "sa_slug", "in": "path", "description": "Service account slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateServiceAccount" } } }, "required": true }, "responses": { "200": { "description": "Service account updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ServiceAccount" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or service account not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/service-accounts/{sa_slug}/api-keys": { "get": { "tags": [ "api-keys" ], "summary": "List API keys by service account", "operationId": "api_key_list_by_service_account", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "sa_slug", "in": "path", "description": "Service account slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of API keys", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKeyListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or service account not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/skills": { "get": { "tags": [ "skills" ], "summary": "List skills by organization.", "operationId": "skill_list_by_org", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of skills", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SkillListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-config": { "get": { "tags": [ "sso" ], "summary": "Get the SSO configuration for an organization", "operationId": "org_sso_config_get", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SSO config found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgSsoConfig" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or SSO config not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "sso" ], "summary": "Create a new SSO configuration for an organization", "description": "Each organization can have at most one SSO configuration. Creating a config\nfor an organization that already has one will result in a 409 Conflict error.", "operationId": "org_sso_config_create", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateOrgSsoConfig" } } }, "required": true }, "responses": { "201": { "description": "SSO config created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgSsoConfig" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Organization already has an SSO config", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "sso" ], "summary": "Delete the SSO configuration for an organization", "operationId": "org_sso_config_delete", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SSO config deleted" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or SSO config not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "sso" ], "summary": "Update the SSO configuration for an organization", "operationId": "org_sso_config_update", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateOrgSsoConfig" } } }, "required": true }, "responses": { "200": { "description": "SSO config updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgSsoConfig" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or SSO config not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-config/domains": { "get": { "tags": [ "domain-verifications" ], "summary": "List all domain verifications for an organization's SSO config", "operationId": "domain_verifications_list", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of items to return", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Domain verifications list", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListDomainVerificationsResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or SSO config not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "domain-verifications" ], "summary": "Initiate domain verification for an organization's SSO config", "description": "Creates a new domain verification record with a unique verification token.\nReturns the verification instructions with DNS record details.", "operationId": "domain_verifications_create", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateDomainVerification" } } }, "required": true }, "responses": { "201": { "description": "Domain verification initiated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainVerification" } } } }, "400": { "description": "Invalid domain or public domain blocked", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or SSO config not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Domain already being verified", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-config/domains/{domain_id}": { "get": { "tags": [ "domain-verifications" ], "summary": "Get a specific domain verification by ID", "operationId": "domain_verifications_get", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "domain_id", "in": "path", "description": "Domain verification ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Domain verification found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainVerification" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization, SSO config, or domain verification not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "domain-verifications" ], "summary": "Delete a domain verification", "operationId": "domain_verifications_delete", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "domain_id", "in": "path", "description": "Domain verification ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Domain verification deleted" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization, SSO config, or domain verification not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-config/domains/{domain_id}/instructions": { "get": { "tags": [ "domain-verifications" ], "summary": "Get verification instructions for a domain", "operationId": "domain_verifications_get_instructions", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "domain_id", "in": "path", "description": "Domain verification ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Verification instructions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DomainVerificationInstructions" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization, SSO config, or domain verification not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-config/domains/{domain_id}/verify": { "post": { "tags": [ "domain-verifications" ], "summary": "Trigger DNS verification for a domain", "description": "Performs a DNS TXT record lookup to verify domain ownership.", "operationId": "domain_verifications_verify", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "domain_id", "in": "path", "description": "Domain verification ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Verification attempt result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifyDomainResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization, SSO config, or domain verification not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-config/saml/parse-metadata": { "post": { "tags": [ "sso" ], "summary": "Parse SAML IdP metadata from a URL", "description": "Fetches IdP metadata from the provided URL and extracts configuration fields.\nThis does NOT save the configuration - it returns the parsed data for admin review.\nUse the returned values to populate the SSO config fields.", "operationId": "org_sso_config_parse_saml_metadata", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ParseSamlMetadataRequest" } } }, "required": true }, "responses": { "200": { "description": "Metadata parsed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ParsedSamlIdpConfig" } } } }, "400": { "description": "Invalid metadata URL or failed to parse", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-config/saml/sp-metadata": { "get": { "tags": [ "sso" ], "summary": "Get SP metadata for IdP configuration", "description": "Returns Hadrian's Service Provider metadata XML that can be imported into\nthe IdP to configure the SAML integration automatically. The metadata includes\nthe SP entity ID, Assertion Consumer Service URL, and supported bindings.\n\nThis endpoint requires an existing SAML SSO configuration for the organization.", "operationId": "org_sso_config_get_sp_metadata", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SP metadata XML", "content": { "application/samlmetadata+xml": {} } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or SAML config not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-group-mappings": { "get": { "tags": [ "sso" ], "summary": "List SSO group mappings for an organization", "operationId": "sso_group_mapping_list", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of SSO group mappings", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SsoGroupMappingListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "sso" ], "summary": "Create a new SSO group mapping", "operationId": "sso_group_mapping_create", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSsoGroupMapping" } } }, "required": true }, "responses": { "201": { "description": "SSO group mapping created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SsoGroupMapping" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-group-mappings/export": { "get": { "tags": [ "sso" ], "summary": "Export SSO group mappings", "description": "Exports all SSO group mappings for an organization in JSON or CSV format.\nUseful for backup, migration, or bulk editing in a spreadsheet.", "operationId": "sso_group_mapping_export", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "format", "in": "query", "description": "Export format (json or csv, defaults to json)", "required": false, "schema": { "$ref": "#/components/schemas/ExportFormat" } }, { "name": "sso_connection_name", "in": "query", "description": "Filter by SSO connection name (optional)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Export of SSO group mappings as CSV", "content": { "text/csv": {} } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-group-mappings/import": { "post": { "tags": [ "sso" ], "summary": "Import SSO group mappings", "description": "Bulk import SSO group mappings from a JSON payload. Useful for migrating\nmappings between environments or restoring from a backup.", "operationId": "sso_group_mapping_import", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImportRequest" } } }, "required": true }, "responses": { "200": { "description": "Import completed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImportResponse" } } } }, "400": { "description": "Invalid request or conflict error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-group-mappings/test": { "post": { "tags": [ "sso" ], "summary": "Test SSO group mapping resolution", "description": "Given a list of IdP group names, returns what teams/roles a user with those\ngroups would be resolved to. This is useful for debugging and verifying\nmapping configuration.", "operationId": "sso_group_mapping_test", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TestMappingRequest" } } }, "required": true }, "responses": { "200": { "description": "Mapping test results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TestMappingResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/sso-group-mappings/{mapping_id}": { "get": { "tags": [ "sso" ], "summary": "Get an SSO group mapping by ID", "operationId": "sso_group_mapping_get", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "mapping_id", "in": "path", "description": "Mapping ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "SSO group mapping found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SsoGroupMapping" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or mapping not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "sso" ], "summary": "Delete an SSO group mapping", "operationId": "sso_group_mapping_delete", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "mapping_id", "in": "path", "description": "Mapping ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "SSO group mapping deleted" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or mapping not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "sso" ], "summary": "Update an SSO group mapping", "operationId": "sso_group_mapping_update", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "mapping_id", "in": "path", "description": "Mapping ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateSsoGroupMapping" } } }, "required": true }, "responses": { "200": { "description": "SSO group mapping updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SsoGroupMapping" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or mapping not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams": { "get": { "tags": [ "teams" ], "summary": "List teams in an organization", "operationId": "team_list", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of teams", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TeamListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "teams" ], "summary": "Create a team in an organization", "operationId": "team_create", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTeam" } } }, "required": true }, "responses": { "201": { "description": "Team created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Team" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict (slug already exists)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}": { "get": { "tags": [ "teams" ], "summary": "Get a team by slug", "operationId": "team_get", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Team found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Team" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "teams" ], "summary": "Delete a team", "operationId": "team_delete", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Team deleted" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "teams" ], "summary": "Update a team", "operationId": "team_update", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTeam" } } }, "required": true }, "responses": { "200": { "description": "Team updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Team" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/members": { "get": { "tags": [ "teams" ], "summary": "List team members", "operationId": "team_member_list", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of team members", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TeamMemberListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "teams" ], "summary": "Add a member to a team", "operationId": "team_member_add", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddTeamMember" } } }, "required": true }, "responses": { "201": { "description": "Member added", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TeamMember" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization, team, or user not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "User is already a member", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/members/{user_id}": { "delete": { "tags": [ "teams" ], "summary": "Remove a member from a team", "operationId": "team_member_remove", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Member removed" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization, team, or membership not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "teams" ], "summary": "Update a team member's role", "operationId": "team_member_update", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTeamMember" } } }, "required": true }, "responses": { "200": { "description": "Member role updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TeamMember" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization, team, or membership not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/skills": { "get": { "tags": [ "skills" ], "summary": "List skills by team.", "operationId": "skill_list_by_team", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of skills", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SkillListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/templates": { "get": { "tags": [ "templates" ], "summary": "List templates by team", "operationId": "template_list_by_team", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of templates", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TemplateListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage": { "get": { "tags": [ "usage" ], "summary": "Get usage summary for a team", "operationId": "usage_get_team_summary", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsageSummaryResponse" } } } }, "404": { "description": "Team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-date": { "get": { "tags": [ "usage" ], "summary": "Get usage by date for a team", "operationId": "usage_get_team_by_date", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailySpendResponse" } } } } }, "404": { "description": "Team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-date-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and model for a team", "operationId": "usage_get_team_by_date_model", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyModelSpendResponse" } } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-date-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and pricing source for a team", "operationId": "usage_get_team_by_date_pricing_source", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyPricingSourceSpendResponse" } } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-date-project": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and project for a team", "operationId": "usage_get_team_by_date_project", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by project", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyProjectSpendResponse" } } } } }, "404": { "description": "Team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-date-provider": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and provider for a team", "operationId": "usage_get_team_by_date_provider", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyProviderSpendResponse" } } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-date-user": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and user for a team", "operationId": "usage_get_team_by_date_user", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyUserSpendResponse" } } } } }, "404": { "description": "Team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by model for a team", "operationId": "usage_get_team_by_model", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ModelSpendResponse" } } } } }, "404": { "description": "Team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get usage by pricing source for a team", "operationId": "usage_get_team_by_pricing_source", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PricingSourceSpendResponse" } } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-project": { "get": { "tags": [ "usage" ], "summary": "Get usage by project for a team", "operationId": "usage_get_team_by_project", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by project", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectSpendResponse" } } } } }, "404": { "description": "Team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-provider": { "get": { "tags": [ "usage" ], "summary": "Get usage by provider for a team", "operationId": "usage_get_team_by_provider", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProviderSpendResponse" } } } } }, "404": { "description": "Team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/by-user": { "get": { "tags": [ "usage" ], "summary": "Get usage by user for a team", "operationId": "usage_get_team_by_user", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserSpendResponse" } } } } }, "404": { "description": "Team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/teams/{team_slug}/usage/forecast": { "get": { "tags": [ "usage" ], "summary": "Get cost forecast for a team", "operationId": "usage_get_team_forecast", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "team_slug", "in": "path", "description": "Team slug", "required": true, "schema": { "type": "string" } }, { "name": "lookback_days", "in": "query", "description": "Number of days of historical data to use (default: 30)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int32" } }, { "name": "forecast_days", "in": "query", "description": "Number of days to forecast ahead (default: 7)", "required": false, "schema": { "type": [ "integer", "null" ], "minimum": 0 } } ], "responses": { "200": { "description": "Cost forecast", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CostForecastResponse" } } } }, "404": { "description": "Team not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{org_slug}/templates": { "get": { "tags": [ "templates" ], "summary": "List templates by organization", "operationId": "template_list_by_org", "parameters": [ { "name": "org_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of templates", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TemplateListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}": { "get": { "tags": [ "organizations" ], "summary": "Get an organization by slug", "operationId": "organization_get", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Organization found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Organization" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "organizations" ], "summary": "Delete an organization", "operationId": "organization_delete", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Organization deleted" }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "organizations" ], "summary": "Update an organization", "operationId": "organization_update", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateOrganization" } } }, "required": true }, "responses": { "200": { "description": "Organization updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Organization" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage": { "get": { "tags": [ "usage" ], "summary": "Get usage summary for an organization", "operationId": "usage_get_org_summary", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsageSummaryResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-date": { "get": { "tags": [ "usage" ], "summary": "Get usage by date for an organization", "operationId": "usage_get_org_by_date", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailySpendResponse" } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-date-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and model for an organization", "operationId": "usage_get_org_by_date_model", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyModelSpendResponse" } } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-date-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and pricing source for an organization", "operationId": "usage_get_org_by_date_pricing_source", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyPricingSourceSpendResponse" } } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-date-project": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and project for an organization", "operationId": "usage_get_org_by_date_project", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by project", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyProjectSpendResponse" } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-date-provider": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and provider for an organization", "operationId": "usage_get_org_by_date_provider", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyProviderSpendResponse" } } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-date-team": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and team for an organization", "operationId": "usage_get_org_by_date_team", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by team", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyTeamSpendResponse" } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-date-user": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and user for an organization", "operationId": "usage_get_org_by_date_user", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyUserSpendResponse" } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by model for an organization", "operationId": "usage_get_org_by_model", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ModelSpendResponse" } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get usage by pricing source for an organization", "operationId": "usage_get_org_by_pricing_source", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PricingSourceSpendResponse" } } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-project": { "get": { "tags": [ "usage" ], "summary": "Get usage by project for an organization", "operationId": "usage_get_org_by_project", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by project", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectSpendResponse" } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-provider": { "get": { "tags": [ "usage" ], "summary": "Get usage by provider for an organization", "operationId": "usage_get_org_by_provider", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProviderSpendResponse" } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-team": { "get": { "tags": [ "usage" ], "summary": "Get usage by team for an organization", "operationId": "usage_get_org_by_team", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by team", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/TeamSpendResponse" } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage/by-user": { "get": { "tags": [ "usage" ], "summary": "Get usage by user for an organization", "operationId": "usage_get_org_by_user", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserSpendResponse" } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/organizations/{slug}/usage/forecast": { "get": { "tags": [ "usage" ], "summary": "Get cost forecast for an organization", "description": "Uses historical usage data across all API keys in the organization to predict future spending.\nReturns average daily spend, confidence intervals, and time series forecasts.", "operationId": "usage_get_org_forecast", "parameters": [ { "name": "slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } }, { "name": "lookback_days", "in": "query", "description": "Number of days of historical data to use (default: 30)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int32" } }, { "name": "forecast_days", "in": "query", "description": "Number of days to forecast ahead (default: 7)", "required": false, "schema": { "type": [ "integer", "null" ], "minimum": 0 } } ], "responses": { "200": { "description": "Cost forecast", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CostForecastResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/providers/circuit-breakers": { "get": { "tags": [ "providers" ], "summary": "Get circuit breaker status for all providers.", "description": "Returns the current state and failure count for all configured\ncircuit breakers. Useful for monitoring provider health.", "operationId": "list_circuit_breakers", "responses": { "200": { "description": "Circuit breaker status for all providers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CircuitBreakersResponse" } } } } } } }, "/admin/v1/providers/health": { "get": { "tags": [ "providers" ], "summary": "Get health status for all providers.", "description": "Returns the current health status for all providers that have health checks\nenabled. Includes status, latency, last check time, and consecutive\nsuccess/failure counts.\n\nNote: Only providers with `health_check.enabled = true` in their config\nwill appear in this list. Providers without health checks rely solely\non circuit breaker status.", "operationId": "list_provider_health", "responses": { "200": { "description": "Health status for all providers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProviderHealthResponse" } } } } } } }, "/admin/v1/providers/stats": { "get": { "tags": [ "providers" ], "summary": "Get aggregated statistics for all providers.", "description": "Returns current metrics including latency percentiles, error counts,\ntoken usage, and costs for all providers.\n\nIn single-node deployments, stats are derived from the local /metrics endpoint.\nIn multi-node deployments with Prometheus configured, stats are aggregated\nfrom Prometheus queries.", "operationId": "list_provider_stats", "responses": { "200": { "description": "Stats for all providers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProviderStatsResponse" } } } }, "500": { "description": "Failed to fetch stats" } } } }, "/admin/v1/providers/{provider_name}/circuit-breaker": { "get": { "tags": [ "providers" ], "summary": "Get circuit breaker status for a specific provider.", "description": "Returns the current state and failure count for the specified provider's\ncircuit breaker.", "operationId": "get_circuit_breaker", "parameters": [ { "name": "provider_name", "in": "path", "description": "Provider name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Circuit breaker status for the provider", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProviderCircuitBreakerResponse" } } } }, "404": { "description": "Provider not found or circuit breaker not enabled" } } } }, "/admin/v1/providers/{provider_name}/health": { "get": { "tags": [ "providers" ], "summary": "Get health status for a specific provider.", "description": "Returns the current health status for the specified provider. Only works\nfor providers that have health checks enabled.", "operationId": "get_provider_health", "parameters": [ { "name": "provider_name", "in": "path", "description": "Provider name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Health status for the provider", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProviderHealthState" } } } }, "404": { "description": "Provider not found or health checks not enabled" } } } }, "/admin/v1/providers/{provider_name}/stats": { "get": { "tags": [ "providers" ], "summary": "Get aggregated statistics for a specific provider.", "description": "Returns current metrics including latency percentiles, error counts,\ntoken usage, and costs for the specified provider.", "operationId": "get_provider_stats", "parameters": [ { "name": "provider_name", "in": "path", "description": "Provider name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Stats for the provider", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProviderStats" } } } }, "404": { "description": "Provider not found or no stats available" } } } }, "/admin/v1/providers/{provider_name}/stats/history": { "get": { "tags": [ "providers" ], "summary": "Get historical statistics for a specific provider.", "description": "Returns time series data for the specified provider within the given\ntime range. Data is returned as hourly or daily buckets depending\non the granularity parameter.\n\n**Note:** Historical stats require Prometheus to be configured via\n`observability.metrics.prometheus_query_url`. In single-node deployments\nwithout Prometheus, this endpoint returns an error.", "operationId": "get_provider_stats_history", "parameters": [ { "name": "provider_name", "in": "path", "description": "Provider name", "required": true, "schema": { "type": "string" } }, { "name": "start", "in": "query", "description": "Start of the time range (defaults to 24 hours ago).", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "end", "in": "query", "description": "End of the time range (defaults to now).", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "granularity", "in": "query", "description": "Granularity of the data points: \"hour\" or \"day\" (defaults to \"hour\").", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Historical stats for the provider", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProviderStatsHistorical" } } } }, "400": { "description": "Invalid query parameters or Prometheus not configured" } } } }, "/admin/v1/providers/{provider}/usage": { "get": { "tags": [ "usage" ], "summary": "Get usage summary for a provider", "operationId": "usage_get_provider_summary", "parameters": [ { "name": "provider", "in": "path", "description": "Provider name", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsageSummaryResponse" } } } } } } }, "/admin/v1/providers/{provider}/usage/by-date": { "get": { "tags": [ "usage" ], "summary": "Get usage by date for a provider", "operationId": "usage_get_provider_by_date", "parameters": [ { "name": "provider", "in": "path", "description": "Provider name", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailySpendResponse" } } } } } } } }, "/admin/v1/providers/{provider}/usage/by-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by model for a provider", "operationId": "usage_get_provider_by_model", "parameters": [ { "name": "provider", "in": "path", "description": "Provider name", "required": true, "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ModelSpendResponse" } } } } } } } }, "/admin/v1/providers/{provider}/usage/forecast": { "get": { "tags": [ "usage" ], "summary": "Get cost forecast for a provider", "description": "Uses historical usage data across all API keys using this provider to predict future spending.\nReturns average daily spend, confidence intervals, and time series forecasts.", "operationId": "usage_get_provider_forecast", "parameters": [ { "name": "provider", "in": "path", "description": "Provider name", "required": true, "schema": { "type": "string" } }, { "name": "lookback_days", "in": "query", "description": "Number of days of historical data to use (default: 30)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int32" } }, { "name": "forecast_days", "in": "query", "description": "Number of days to forecast ahead (default: 7)", "required": false, "schema": { "type": [ "integer", "null" ], "minimum": 0 } } ], "responses": { "200": { "description": "Cost forecast", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CostForecastResponse" } } } } } } }, "/admin/v1/rbac-policies/validate": { "post": { "tags": [ "rbac-policies" ], "summary": "Validate a CEL expression", "description": "Checks if a CEL expression is syntactically valid without creating a policy.\nUseful for validating expressions before saving.", "operationId": "org_rbac_policy_validate", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ValidateCelRequest" } } }, "required": true }, "responses": { "200": { "description": "Validation result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ValidateCelResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/session-info": { "get": { "tags": [ "session" ], "summary": "Get comprehensive session and access information.", "description": "Returns detailed information about the current user's authentication state,\ndatabase profile, organization/team/project memberships, and SSO configuration.\nUseful for debugging authentication and authorization issues.", "operationId": "session_info_get", "responses": { "200": { "description": "Session information", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SessionInfoResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/skills": { "post": { "tags": [ "skills" ], "summary": "Create a skill.", "operationId": "skill_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSkill" } } }, "required": true }, "responses": { "201": { "description": "Skill created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Skill" } } } }, "400": { "description": "Invalid skill (missing SKILL.md, duplicate path, or size limit exceeded)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Owner not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Skill with this name already exists for this owner", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/skills/{id}": { "get": { "tags": [ "skills" ], "summary": "Get a skill by ID (with full file contents).", "operationId": "skill_get", "parameters": [ { "name": "id", "in": "path", "description": "Skill ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Skill found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Skill" } } } }, "404": { "description": "Skill not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "skills" ], "summary": "Soft-delete a skill.", "operationId": "skill_delete", "parameters": [ { "name": "id", "in": "path", "description": "Skill ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Skill deleted" }, "404": { "description": "Skill not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "skills" ], "summary": "Update a skill.", "description": "When `files` is provided, the full file set is replaced.", "operationId": "skill_update", "parameters": [ { "name": "id", "in": "path", "description": "Skill ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateSkill" } } }, "required": true }, "responses": { "200": { "description": "Skill updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Skill" } } } }, "400": { "description": "Invalid skill (missing SKILL.md, duplicate path, or size limit exceeded)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Skill not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Skill with this name already exists for this owner", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/sso-connections": { "get": { "tags": [ "sso" ], "summary": "List configured SSO connections", "description": "Returns read-only information about SSO connections configured in the gateway.\nSSO connections are defined in the config file (hadrian.toml), not the database.\nCurrently only one OIDC connection is supported per deployment.", "operationId": "sso_connections_list", "responses": { "200": { "description": "List of SSO connections", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SsoConnectionsResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/sso-connections/{name}": { "get": { "tags": [ "sso" ], "summary": "Get a specific SSO connection by name", "operationId": "sso_connection_get", "parameters": [ { "name": "name", "in": "path", "description": "SSO connection name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SSO connection found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SsoConnection" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "SSO connection not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/templates": { "post": { "tags": [ "templates" ], "summary": "Create a template", "operationId": "template_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTemplate" } } }, "required": true }, "responses": { "201": { "description": "Template created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Template" } } } }, "404": { "description": "Owner not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Template with this name already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/templates/{id}": { "get": { "tags": [ "templates" ], "summary": "Get a template by ID", "operationId": "template_get", "parameters": [ { "name": "id", "in": "path", "description": "Template ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Template found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Template" } } } }, "404": { "description": "Template not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "templates" ], "summary": "Delete a template", "operationId": "template_delete", "parameters": [ { "name": "id", "in": "path", "description": "Template ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Template deleted" }, "404": { "description": "Template not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "templates" ], "summary": "Update a template", "operationId": "template_update", "parameters": [ { "name": "id", "in": "path", "description": "Template ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTemplate" } } }, "required": true }, "responses": { "200": { "description": "Template updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Template" } } } }, "404": { "description": "Template not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Template with this name already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/usage": { "get": { "tags": [ "usage" ], "summary": "Get global usage summary", "operationId": "usage_get_global_summary", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Global usage summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsageSummaryResponse" } } } } } } }, "/admin/v1/usage/by-date": { "get": { "tags": [ "usage" ], "summary": "Get global usage by date", "operationId": "usage_get_global_by_date", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailySpendResponse" } } } } } } } }, "/admin/v1/usage/by-date-model": { "get": { "tags": [ "usage" ], "summary": "Get global usage by date and model", "operationId": "usage_get_global_by_date_model", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyModelSpendResponse" } } } } } } } }, "/admin/v1/usage/by-date-org": { "get": { "tags": [ "usage" ], "summary": "Get global usage by date and organization", "operationId": "usage_get_global_by_date_org", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by organization", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyOrgSpendResponse" } } } } } } } }, "/admin/v1/usage/by-date-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get global usage by date and pricing source", "operationId": "usage_get_global_by_date_pricing_source", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyPricingSourceSpendResponse" } } } } } } } }, "/admin/v1/usage/by-date-project": { "get": { "tags": [ "usage" ], "summary": "Get global usage by date and project", "operationId": "usage_get_global_by_date_project", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by project", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyProjectSpendResponse" } } } } } } } }, "/admin/v1/usage/by-date-provider": { "get": { "tags": [ "usage" ], "summary": "Get global usage by date and provider", "operationId": "usage_get_global_by_date_provider", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyProviderSpendResponse" } } } } } } } }, "/admin/v1/usage/by-date-team": { "get": { "tags": [ "usage" ], "summary": "Get global usage by date and team", "operationId": "usage_get_global_by_date_team", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by team", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyTeamSpendResponse" } } } } } } } }, "/admin/v1/usage/by-date-user": { "get": { "tags": [ "usage" ], "summary": "Get global usage by date and user", "operationId": "usage_get_global_by_date_user", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyUserSpendResponse" } } } } } } } }, "/admin/v1/usage/by-model": { "get": { "tags": [ "usage" ], "summary": "Get global usage by model", "operationId": "usage_get_global_by_model", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ModelSpendResponse" } } } } } } } }, "/admin/v1/usage/by-org": { "get": { "tags": [ "usage" ], "summary": "Get global usage by organization", "operationId": "usage_get_global_by_org", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by organization", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/OrgSpendResponse" } } } } } } } }, "/admin/v1/usage/by-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get global usage by pricing source", "operationId": "usage_get_global_by_pricing_source", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PricingSourceSpendResponse" } } } } } } } }, "/admin/v1/usage/by-project": { "get": { "tags": [ "usage" ], "summary": "Get global usage by project", "operationId": "usage_get_global_by_project", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by project", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectSpendResponse" } } } } } } } }, "/admin/v1/usage/by-provider": { "get": { "tags": [ "usage" ], "summary": "Get global usage by provider", "operationId": "usage_get_global_by_provider", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProviderSpendResponse" } } } } } } } }, "/admin/v1/usage/by-team": { "get": { "tags": [ "usage" ], "summary": "Get global usage by team", "operationId": "usage_get_global_by_team", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by team", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/TeamSpendResponse" } } } } } } } }, "/admin/v1/usage/by-user": { "get": { "tags": [ "usage" ], "summary": "Get global usage by user", "operationId": "usage_get_global_by_user", "parameters": [ { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserSpendResponse" } } } } } } } }, "/admin/v1/usage/logs": { "get": { "tags": [ "usage" ], "summary": "List usage logs (admin global)", "operationId": "usage_log_list", "parameters": [ { "name": "org_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "user_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "project_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "team_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "api_key_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "service_account_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "model", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "provider", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "provider_source", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "from", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "to", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "limit", "in": "query", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "List of usage log records", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsageLogListResponse" } } } } } } }, "/admin/v1/usage/logs/export": { "get": { "tags": [ "usage" ], "summary": "Export usage logs (admin global)", "operationId": "usage_log_export", "parameters": [ { "name": "org_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "user_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "project_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "team_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "api_key_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "service_account_id", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "model", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "provider", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "provider_source", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "from", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "to", "in": "query", "required": false, "schema": { "type": [ "string", "null" ], "format": "date-time" } }, { "name": "format", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/UsageLogExportFormat" } } ], "responses": { "200": { "description": "Exported usage logs", "content": { "application/x-ndjson": {} } } } } }, "/admin/v1/users": { "get": { "tags": [ "users" ], "summary": "List all users", "operationId": "user_list", "parameters": [ { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of users", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "tags": [ "users" ], "summary": "Create a user", "operationId": "user_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateUser" } } }, "required": true }, "responses": { "201": { "description": "User created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict (external_id already exists)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}": { "get": { "tags": [ "users" ], "summary": "Get a user by ID", "operationId": "user_get", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "users" ], "summary": "Delete a user and all associated data (GDPR Article 17 - Right to Erasure)", "description": "Permanently deletes the user and all associated data including:\n- User record\n- Organization and project memberships\n- API keys owned by the user\n- Conversations owned by the user\n- Dynamic providers owned by the user\n- Usage records for user's API keys\n\nThis operation is irreversible.", "operationId": "user_delete", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User deleted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserDeletionResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "tags": [ "users" ], "summary": "Update a user", "operationId": "user_update", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateUser" } } }, "required": true }, "responses": { "200": { "description": "User updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/access-summary": { "get": { "tags": [ "access-reviews" ], "summary": "Get access summary for a specific user", "description": "Returns a comprehensive access summary for the specified user including:\n- All organizations the user belongs to with roles and grant dates\n- All projects the user belongs to with roles and grant dates\n- All API keys owned by the user\n- Last activity timestamps per resource\n- Summary statistics\n\nUse `format=csv` for CSV export suitable for auditors and spreadsheets.", "operationId": "user_access_summary", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "format", "in": "query", "description": "Export format (json or csv)", "required": false, "schema": { "oneOf": [ { "$ref": "#/components/schemas/ExportFormat" } ], "default": "json" } } ], "responses": { "200": { "description": "User access summary (JSON or CSV based on format parameter)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserAccessSummaryResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/api-keys": { "get": { "tags": [ "api-keys" ], "summary": "List API keys by user", "operationId": "api_key_list_by_user", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of API keys", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKeyListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/conversations": { "get": { "tags": [ "conversations" ], "summary": "List conversations by user", "operationId": "conversation_list_by_user", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of conversations", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/conversations/accessible": { "get": { "tags": [ "conversations" ], "summary": "List all conversations accessible to a user", "description": "Returns both user's personal conversations and conversations from projects they belong to.\nResults include project metadata when applicable.", "operationId": "conversation_list_accessible_for_user", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of conversations to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64", "maximum": 1000, "minimum": 1 } } ], "responses": { "200": { "description": "List of accessible conversations", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationWithProjectListResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/dynamic-providers": { "get": { "tags": [ "dynamic-providers" ], "summary": "List dynamic providers by user", "operationId": "dynamic_provider_list_by_user", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of dynamic providers", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DynamicProviderListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/export": { "get": { "tags": [ "users" ], "summary": "Export all user data (GDPR Article 15 - Right of Access)", "description": "Returns all personal data associated with the user including:\n- User profile\n- Organization and project memberships\n- API keys (excluding sensitive hash)\n- Conversations\n- Usage summary\n- Audit logs where user was the actor", "operationId": "user_export", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User data export", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserDataExport" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/model-pricing": { "get": { "tags": [ "model-pricing" ], "summary": "List model pricing for a user", "operationId": "model_pricing_list_by_user", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of user model pricing", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModelPricingListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/sessions": { "get": { "tags": [ "users" ], "summary": "List all active sessions for a user.", "description": "Returns an empty list if enhanced session management is not enabled.\nThe `enhanced_enabled` field indicates whether session tracking is active.", "operationId": "user_sessions_list", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "List of user sessions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SessionListResponse" } } } }, "400": { "description": "User has no external_id (API-only user)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "tags": [ "users" ], "summary": "Revoke all sessions for a user (force logout).", "description": "This is the critical endpoint for the \"terminated employee\" use case.\nReturns 0 sessions revoked if enhanced session management is not enabled.", "operationId": "user_sessions_delete_all", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "All sessions revoked", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SessionsRevokedResponse" } } } }, "400": { "description": "User has no external_id (API-only user)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/sessions/{session_id}": { "delete": { "tags": [ "users" ], "summary": "Revoke a specific session for a user.", "description": "Returns success even if the session doesn't exist (idempotent).", "operationId": "user_sessions_delete_one", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "session_id", "in": "path", "description": "Session ID to revoke", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Session revoked", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SessionsRevokedResponse" } } } }, "400": { "description": "User has no external_id or session doesn't belong to user", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Access denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/skills": { "get": { "tags": [ "skills" ], "summary": "List skills by user.", "operationId": "skill_list_by_user", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of skills", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SkillListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/templates": { "get": { "tags": [ "templates" ], "summary": "List templates by user", "operationId": "template_list_by_user", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of results to return", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64" } }, { "name": "cursor", "in": "query", "description": "Cursor for keyset pagination. Encoded as base64 string.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "direction", "in": "query", "description": "Pagination direction: \"forward\" (default) or \"backward\".", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "include_deleted", "in": "query", "description": "Include soft-deleted records in results", "required": false, "schema": { "type": [ "boolean", "null" ] } } ], "responses": { "200": { "description": "List of templates", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TemplateListResponse" } } } }, "400": { "description": "Invalid cursor or direction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/usage": { "get": { "tags": [ "usage" ], "summary": "Get usage summary for a user", "operationId": "usage_get_user_summary", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsageSummaryResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/usage/by-date": { "get": { "tags": [ "usage" ], "summary": "Get usage by date for a user", "operationId": "usage_get_user_by_date", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailySpendResponse" } } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/usage/by-date-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and model for a user", "operationId": "usage_get_user_by_date_model", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyModelSpendResponse" } } } } } } } }, "/admin/v1/users/{user_id}/usage/by-date-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and pricing source for a user", "operationId": "usage_get_user_by_date_pricing_source", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyPricingSourceSpendResponse" } } } } } } } }, "/admin/v1/users/{user_id}/usage/by-date-provider": { "get": { "tags": [ "usage" ], "summary": "Get usage by date and provider for a user", "operationId": "usage_get_user_by_date_provider", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Daily usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DailyProviderSpendResponse" } } } } } } } }, "/admin/v1/users/{user_id}/usage/by-model": { "get": { "tags": [ "usage" ], "summary": "Get usage by model for a user", "operationId": "usage_get_user_by_model", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by model", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ModelSpendResponse" } } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/usage/by-pricing-source": { "get": { "tags": [ "usage" ], "summary": "Get usage by pricing source for a user", "operationId": "usage_get_user_by_pricing_source", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by pricing source", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PricingSourceSpendResponse" } } } } } } } }, "/admin/v1/users/{user_id}/usage/by-provider": { "get": { "tags": [ "usage" ], "summary": "Get usage by provider for a user", "operationId": "usage_get_user_by_provider", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "query", "description": "Start date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "end_date", "in": "query", "description": "End date (YYYY-MM-DD)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Usage breakdown by provider", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ProviderSpendResponse" } } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/admin/v1/users/{user_id}/usage/forecast": { "get": { "tags": [ "usage" ], "summary": "Get cost forecast for a user", "description": "Uses historical usage data across all API keys owned by the user to predict future spending.\nReturns average daily spend, confidence intervals, and time series forecasts.", "operationId": "usage_get_user_forecast", "parameters": [ { "name": "user_id", "in": "path", "description": "User ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "lookback_days", "in": "query", "description": "Number of days of historical data to use (default: 30)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int32" } }, { "name": "forecast_days", "in": "query", "description": "Number of days to forecast ahead (default: 7)", "required": false, "schema": { "type": [ "integer", "null" ], "minimum": 0 } } ], "responses": { "200": { "description": "Cost forecast", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CostForecastResponse" } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/v1/audio/speech": { "post": { "tags": [ "Audio" ], "summary": "Generate speech from text", "description": "POST /v1/audio/speech", "operationId": "api_v1_audio_speech", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSpeechRequest" } } }, "required": true }, "responses": { "200": { "description": "Audio generated successfully", "content": { "audio/mpeg": {} } }, "400": { "description": "Bad request" }, "500": { "description": "Internal server error" } }, "security": [ { "api_key": [] } ] } }, "/api/v1/audio/transcriptions": { "post": { "tags": [ "Audio" ], "summary": "Transcribe audio to text", "description": "POST /v1/audio/transcriptions", "operationId": "api_v1_audio_transcriptions", "requestBody": { "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/CreateTranscriptionRequest" } } }, "required": true }, "responses": { "200": { "description": "Audio transcribed successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TranscriptionResponse" } } } }, "400": { "description": "Bad request" }, "500": { "description": "Internal server error" } }, "security": [ { "api_key": [] } ] } }, "/api/v1/audio/translations": { "post": { "tags": [ "Audio" ], "summary": "Translate audio to English text", "description": "POST /v1/audio/translations", "operationId": "api_v1_audio_translations", "requestBody": { "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/CreateTranslationRequest" } } }, "required": true }, "responses": { "200": { "description": "Audio translated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TranslationResponse" } } } }, "400": { "description": "Bad request" }, "500": { "description": "Internal server error" } }, "security": [ { "api_key": [] } ] } }, "/api/v1/chat/completions": { "post": { "tags": [ "chat" ], "summary": "Create a chat completion", "description": "Creates a model response for the given chat conversation. Supports both streaming and\nnon-streaming responses. The model can be specified using provider prefixes (e.g.,\n`openai/gpt-4o`) or with dynamic routing for multi-tenant configurations.", "operationId": "api_v1_chat_completions", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateChatCompletionPayload" }, "examples": { "Simple": { "summary": "Simple text completion", "value": { "model": "openai/gpt-4o", "messages": [ { "role": "user", "content": "Hello, how are you?" } ] } }, "Streaming": { "summary": "Streaming completion", "value": { "model": "openai/gpt-4o", "messages": [ { "role": "user", "content": "Write a short poem about coding." } ], "stream": true } }, "With system prompt": { "summary": "Completion with system prompt and parameters", "value": { "model": "anthropic/claude-sonnet-4-20250514", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "Explain quantum computing in simple terms." } ], "max_tokens": 500, "temperature": 0.7 } }, "With tools": { "summary": "Completion with function calling", "value": { "model": "openai/gpt-4o", "messages": [ { "role": "user", "content": "What's the weather in San Francisco?" } ], "tools": [ { "type": "function", "function": { "name": "get_weather", "description": "Get the current weather for a location", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "City name" } }, "required": [ "location" ] } } } ], "tool_choice": "auto" } } } } }, "required": true }, "responses": { "200": { "description": "Chat completion response (streaming returns SSE events)" }, "400": { "description": "Bad request - invalid model, missing fields, or validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": { "code": "routing_error", "message": "Model 'invalid-model' not found" } } } } }, "401": { "description": "Unauthorized - invalid or missing API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": { "code": "invalid_api_key", "message": "Invalid API key provided" } } } } }, "429": { "description": "Rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": { "code": "rate_limit_exceeded", "message": "Rate limit exceeded: 100 requests per minute", "details": { "limit": 100, "window": "minute", "retry_after_secs": 30 } } } } } }, "502": { "description": "Provider error - upstream LLM provider returned an error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": { "code": "provider_error", "message": "Upstream provider returned error: Service temporarily unavailable" } } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/completions": { "post": { "tags": [ "completions" ], "summary": "Create a text completion", "description": "Creates a completion for the provided prompt and parameters.", "operationId": "api_v1_completions", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCompletionPayload" } } }, "required": true }, "responses": { "200": { "description": "Completion response (streaming or non-streaming)" }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "502": { "description": "Provider error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/containers": { "get": { "tags": [ "containers" ], "summary": "`GET /v1/containers` — list containers in the caller's org,\nnewest-first. Matches OpenAI's cursor pagination shape.", "operationId": "api_v1_containers_list", "parameters": [ { "name": "limit", "in": "query", "description": "Page size, clamped to 1..=100 (default 20)", "required": false, "schema": { "type": "integer", "format": "int64" } }, { "name": "after", "in": "query", "description": "Cursor: cntr_ id of the last item from a prior page", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Containers in the org" }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Persistence disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "post": { "tags": [ "containers" ], "summary": "`POST /v1/containers` — create an unattached container.", "operationId": "api_v1_containers_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateContainerRequest" } } }, "required": true }, "responses": { "200": { "description": "The created container metadata" }, "400": { "description": "Request rejected", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Persistence disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/containers/{container_id}": { "get": { "tags": [ "containers" ], "summary": "`GET /v1/containers/{container_id}` — retrieve a container.", "operationId": "api_v1_containers_get", "parameters": [ { "name": "container_id", "in": "path", "description": "Container ID (`cntr_`)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The container metadata" }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Container not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Persistence disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "delete": { "tags": [ "containers" ], "summary": "`DELETE /v1/containers/{container_id}` — soft-delete a container.", "description": "Sets `status='deleted'` and evicts the matching in-memory session\nfrom the registry so the VM is torn down on the next Arc drop.\nThe underlying `container_files` rows cascade-delete with the\ncontainer row.", "operationId": "api_v1_containers_delete", "parameters": [ { "name": "container_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Container deleted" }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Container not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Persistence disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/containers/{container_id}/files": { "get": { "tags": [ "containers" ], "summary": "`GET /v1/containers/{container_id}/files` — list files.", "operationId": "api_v1_containers_list_files", "parameters": [ { "name": "container_id", "in": "path", "description": "Container ID", "required": true, "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Page size, clamped to 1..=1000", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Files in the container" }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Container not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Persistence disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "post": { "tags": [ "containers" ], "summary": "`POST /v1/containers/{container_id}/files` — upload a file into a\ncontainer's `/mnt/data`. Accepts either:", "description": "- `multipart/form-data` with a `file` part (required) and optional\n `path` / `content_type` parts — streams bytes directly.\n- `application/json` with `{file_id: \"file_...\"}` — copies an\n existing Files-API upload into the container (same resolver as\n the `file_ids` array on `POST /v1/containers`).\n\nMatches OpenAI's upload contract.", "operationId": "api_v1_containers_file_upload", "parameters": [ { "name": "container_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Uploaded file metadata" }, "400": { "description": "Request rejected", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Container not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "413": { "description": "Payload too large", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "415": { "description": "Unsupported Content-Type", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Persistence disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/containers/{container_id}/files/{file_id}": { "get": { "tags": [ "containers" ], "summary": "`GET /v1/containers/{container_id}/files/{file_id}` — file metadata.", "operationId": "api_v1_containers_file_get", "parameters": [ { "name": "container_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "file_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The container file metadata" }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "File not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Persistence disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "delete": { "tags": [ "containers" ], "summary": "`DELETE /v1/containers/{container_id}/files/{file_id}` — remove\na file from a container.", "operationId": "api_v1_containers_file_delete", "parameters": [ { "name": "container_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "file_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "File deleted" }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "File not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Persistence disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/containers/{container_id}/files/{file_id}/content": { "get": { "tags": [ "containers" ], "summary": "`GET /v1/containers/{container_id}/files/{file_id}/content` — raw bytes.", "operationId": "api_v1_containers_file_content", "parameters": [ { "name": "container_id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "file_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Raw file bytes; Content-Type comes from the row" }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "File not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Persistence disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/embeddings": { "post": { "tags": [ "embeddings" ], "summary": "Create embeddings", "description": "Creates an embedding vector representing the input text. Embeddings are useful for\nsemantic search, clustering, classification, and similarity comparisons.", "operationId": "api_v1_embeddings", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateEmbeddingPayload" }, "examples": { "Multiple texts": { "summary": "Embed multiple texts in one request", "value": { "model": "openai/text-embedding-3-large", "input": [ "First document to embed", "Second document to embed", "Third document to embed" ], "dimensions": 1024 } }, "Single text": { "summary": "Embed a single text string", "value": { "model": "openai/text-embedding-3-small", "input": "Hello world" } } } } }, "required": true }, "responses": { "200": { "description": "Embedding vectors for the input text(s)" }, "400": { "description": "Bad request - invalid model or input", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": { "code": "routing_error", "message": "Model 'invalid-embedding-model' not found" } } } } }, "502": { "description": "Provider error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": { "code": "provider_error", "message": "Upstream provider returned error" } } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/files": { "get": { "tags": [ "files" ], "summary": "List files", "description": "Returns a list of files owned by the specified owner.", "operationId": "file_list", "parameters": [ { "name": "limit", "in": "query", "description": "Maximum number of files to return (default: 20, max: 100)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64", "maximum": 100, "minimum": 1 } }, { "name": "order", "in": "query", "description": "Sort order by `created_at` timestamp (default: desc)", "required": false, "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SortOrder" } ] } }, { "name": "after", "in": "query", "description": "Cursor for forward pagination. Returns results after this file ID.", "required": false, "schema": { "type": [ "string", "null" ] }, "example": "file-550e8400-e29b-41d4-a716-446655440000" }, { "name": "before", "in": "query", "description": "**Hadrian Extension:** Cursor for backward pagination. Returns results before this file ID.", "required": false, "schema": { "type": [ "string", "null" ] }, "example": "file-550e8400-e29b-41d4-a716-446655440000" }, { "name": "purpose", "in": "query", "description": "Filter by purpose", "required": false, "schema": { "type": [ "string", "null" ] }, "example": "assistants" }, { "name": "owner_type", "in": "query", "description": "**Hadrian Extension:** Owner type for multi-tenancy (organization, project, or user)", "required": true, "schema": { "type": "string" } }, { "name": "owner_id", "in": "query", "description": "**Hadrian Extension:** Owner ID for multi-tenancy", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "List of files", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FileListResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "post": { "tags": [ "files" ], "summary": "Upload a file", "description": "Uploads a file that can be used with vector stores for RAG.\nFiles are uploaded as multipart/form-data with the following fields:\n- `file`: The file to upload (required)\n- `purpose`: The intended purpose of the file (default: \"assistants\")\n- `owner_type`: Owner type - \"organization\", \"project\", or \"user\" (required)\n- `owner_id`: Owner ID (required)", "operationId": "file_upload", "requestBody": { "description": "File upload with metadata", "content": { "multipart/form-data": {} } }, "responses": { "200": { "description": "File uploaded successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/File" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "413": { "description": "File too large", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "422": { "description": "Virus detected in uploaded file", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/files/{file_id}": { "get": { "tags": [ "files" ], "summary": "Get file metadata", "description": "Returns information about a specific file.", "operationId": "file_get", "parameters": [ { "name": "file_id", "in": "path", "description": "File ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "File metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/File" } } } }, "404": { "description": "File not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "delete": { "tags": [ "files" ], "summary": "Delete a file", "description": "Deletes a file. The file cannot be deleted if it is still referenced by any vector stores.", "operationId": "file_delete", "parameters": [ { "name": "file_id", "in": "path", "description": "File ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "File deleted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeleteFileResponse" } } } }, "400": { "description": "File is still in use", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "File not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/files/{file_id}/content": { "get": { "tags": [ "files" ], "summary": "Get file content", "description": "Returns the content of a file.", "operationId": "file_get_content", "parameters": [ { "name": "file_id", "in": "path", "description": "File ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "File content", "content": { "application/octet-stream": {} } }, "404": { "description": "File not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/images/edits": { "post": { "tags": [ "Images" ], "summary": "Edit image with text instructions", "description": "POST /v1/images/edits", "operationId": "api_v1_images_edits", "requestBody": { "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/CreateImageEditRequest" } } }, "required": true }, "responses": { "200": { "description": "Image edited successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImagesResponse" } } } }, "400": { "description": "Bad request" }, "500": { "description": "Internal server error" } }, "security": [ { "api_key": [] } ] } }, "/api/v1/images/generations": { "post": { "tags": [ "Images" ], "summary": "Create image from text prompt", "description": "POST /v1/images/generations", "operationId": "api_v1_images_generations", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateImageRequest" } } }, "required": true }, "responses": { "200": { "description": "Image generated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImagesResponse" } } } }, "400": { "description": "Bad request" }, "500": { "description": "Internal server error" } }, "security": [ { "api_key": [] } ] } }, "/api/v1/images/variations": { "post": { "tags": [ "Images" ], "summary": "Create image variations", "description": "POST /v1/images/variations", "operationId": "api_v1_images_variations", "requestBody": { "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/CreateImageVariationRequest" } } }, "required": true }, "responses": { "200": { "description": "Image variations created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ImagesResponse" } } } }, "400": { "description": "Bad request" }, "500": { "description": "Internal server error" } }, "security": [ { "api_key": [] } ] } }, "/api/v1/models": { "get": { "tags": [ "models" ], "summary": "List available models", "description": "Lists all models available from all configured providers.", "operationId": "api_v1_models", "responses": { "200": { "description": "List of available models", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CombinedModelsResponse" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/responses": { "post": { "tags": [ "chat" ], "summary": "Create a response", "description": "Creates a model response using the Responses API format.", "operationId": "api_v1_responses", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateResponsesPayload" } } }, "required": true }, "responses": { "200": { "description": "Response object (streaming or non-streaming)" }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "502": { "description": "Provider error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/responses/compact": { "post": { "tags": [ "responses" ], "summary": "Compact a context window via the provider's standalone compact\nendpoint.", "description": "Stateless passthrough: forwards `model` + `input` (and any other\nfields the provider accepts) to the upstream `/responses/compact`\nendpoint and streams the compacted window back. Only OpenAI and\nAzure OpenAI implement this; routing to any other provider returns\n501 with `error_code = \"not_supported\"`.", "operationId": "api_v1_responses_compact", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompactRequest" } } }, "required": true }, "responses": { "200": { "description": "Compacted context window" }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Provider does not support compaction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/responses/{response_id}": { "get": { "tags": [ "responses" ], "summary": "`GET /v1/responses/{response_id}` — retrieve a stored response.", "description": "When `?stream=true` is set, returns the persisted event log as an\nSSE stream (matching OpenAI's retrieve-with-stream behavior). The\n`starting_after` query parameter resumes replay from a specific\nsequence number so a client reconnecting after a disconnect picks\nup exactly where it stopped.", "operationId": "api_v1_responses_get", "parameters": [ { "name": "response_id", "in": "path", "description": "ID returned by POST /v1/responses", "required": true, "schema": { "type": "string" } }, { "name": "stream", "in": "query", "description": "Stream the event log as SSE", "required": false, "schema": { "type": "boolean" } }, { "name": "starting_after", "in": "query", "description": "Resume cursor (stream mode)", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Stored response (JSON) or SSE replay when stream=true" }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Response not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "501": { "description": "Persistence disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "delete": { "tags": [ "responses" ], "summary": "`DELETE /v1/responses/{response_id}` — remove a stored response.\nReturns the OpenAI-spec deletion confirmation shape.", "operationId": "api_v1_responses_delete", "parameters": [ { "name": "response_id", "in": "path", "description": "ID of the response to delete", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Deletion confirmation" }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/responses/{response_id}/cancel": { "post": { "tags": [ "responses" ], "summary": "`POST /v1/responses/{response_id}/cancel` — cancel an in-progress\nbackground response. Per OpenAI's spec, returns 400 if the response\nis not in background mode. Idempotent for already-terminal rows.", "operationId": "api_v1_responses_cancel", "parameters": [ { "name": "response_id", "in": "path", "description": "ID of the response to cancel", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The cancelled response object" }, "400": { "description": "Response is not in background mode", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Authentication required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Authorization denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Response not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/tools/web-fetch": { "post": { "tags": [ "Tools" ], "summary": "Fetch a web page", "description": "Fetches a URL and returns its content, optionally stripping HTML tags.\n\n**Hadrian Extension:** This endpoint is not part of the OpenAI API specification.", "operationId": "web_fetch", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebFetchRequest" } } }, "required": true }, "responses": { "200": { "description": "Fetched content", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebFetchResponse" } } } }, "400": { "description": "Bad request or blocked URL" }, "404": { "description": "Web fetch not configured" } }, "security": [ { "api_key": [] } ] } }, "/api/v1/tools/web-search": { "post": { "tags": [ "Tools" ], "summary": "Search the web", "description": "Performs a web search using the configured search provider (Tavily or Exa).\n\n**Hadrian Extension:** This endpoint is not part of the OpenAI API specification.", "operationId": "web_search", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebSearchRequest" } } }, "required": true }, "responses": { "200": { "description": "Search results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebSearchResponse" } } } }, "400": { "description": "Bad request" }, "404": { "description": "Web search not configured" } }, "security": [ { "api_key": [] } ] } }, "/api/v1/vector_stores": { "get": { "tags": [ "vector-stores" ], "summary": "List vector stores", "description": "Returns a list of vector stores owned by the specified owner.", "operationId": "vector_store_list", "parameters": [ { "name": "owner_type", "in": "query", "description": "**Hadrian Extension:** Owner type for multi-tenancy (organization, team, project, or user).\nWhen omitted along with `owner_id`, returns all accessible vector stores.", "required": false, "schema": { "type": [ "string", "null" ] } }, { "name": "owner_id", "in": "query", "description": "**Hadrian Extension:** Owner ID for multi-tenancy.\nWhen omitted along with `owner_type`, returns all accessible vector stores.", "required": false, "schema": { "type": [ "string", "null" ], "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of vector stores to return (default: 20, max: 100)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64", "maximum": 100, "minimum": 1 } }, { "name": "order", "in": "query", "description": "Sort order by `created_at` timestamp (default: desc)", "required": false, "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SortOrder" } ] } }, { "name": "after", "in": "query", "description": "Cursor for forward pagination. Returns results after this object ID.\nUse the `last_id` from a previous response to get the next page.", "required": false, "schema": { "type": [ "string", "null" ] }, "example": "vs_550e8400-e29b-41d4-a716-446655440000" }, { "name": "before", "in": "query", "description": "Cursor for backward pagination. Returns results before this object ID.\nUse the `first_id` from a previous response to get the previous page.", "required": false, "schema": { "type": [ "string", "null" ] }, "example": "vs_550e8400-e29b-41d4-a716-446655440000" } ], "responses": { "200": { "description": "List of vector stores", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorStoreListResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "post": { "tags": [ "vector-stores" ], "summary": "Create a vector store", "description": "Creates a new vector store for storing file embeddings.\nOptionally attaches files to the vector store at creation time via `file_ids`.", "operationId": "vector_store_create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateVectorStore" } } }, "required": true }, "responses": { "201": { "description": "Vector store created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorStore" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Owner not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/vector_stores/{vector_store_id}": { "get": { "tags": [ "vector-stores" ], "summary": "Get a vector store", "description": "Retrieves a vector store by ID.", "operationId": "vector_store_get", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID (e.g., vs_550e8400-e29b-41d4-a716-446655440000)", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Vector store details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorStore" } } } }, "404": { "description": "Vector store not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "post": { "tags": [ "vector-stores" ], "summary": "Modify a vector store", "description": "Modifies a vector store's metadata.", "operationId": "vector_store_modify", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateVectorStore" } } }, "required": true }, "responses": { "200": { "description": "Vector store updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorStore" } } } }, "404": { "description": "Vector store not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "delete": { "tags": [ "vector-stores" ], "summary": "Delete a vector store", "description": "Deletes a vector store and all its files (soft delete).", "operationId": "vector_store_delete", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Vector store deleted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeleteVectorStoreResponse" } } } }, "404": { "description": "Vector store not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/vector_stores/{vector_store_id}/file_batches": { "post": { "tags": [ "vector-stores" ], "summary": "Create a file batch", "description": "Creates a batch of files to be added to a vector store.\nNote: File batches are not yet fully implemented. This endpoint creates\nfiles individually and returns a batch representation.\n\n## Content Deduplication\n\nFiles are deduplicated by content hash (SHA-256). If a file with identical content\nalready exists in the vector store, it is counted as \"completed\" in the batch\nresponse but no re-processing occurs. This prevents duplicate chunks and wasted\ncompute while still reporting success for the file.\n\nThe `file_counts.completed` field in the response includes both newly processed\nfiles and deduplicated files.\n\n## Embedding Model Validation\n\nThe gateway validates that its configured embedding model matches the vector store's\nembedding model before processing any files in the batch. This prevents incompatible\nembeddings from being stored together. If there's a mismatch, a 409 Conflict error\nis returned with details about the expected vs. configured models.", "operationId": "vector_store_file_batch_create", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateFileBatchRequest" } } }, "required": true }, "responses": { "201": { "description": "File batch created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FileBatch" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Vector store not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Embedding model mismatch", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "File search service not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/vector_stores/{vector_store_id}/file_batches/{batch_id}": { "get": { "tags": [ "vector-stores" ], "summary": "Get a file batch", "description": "Retrieves a file batch. Note: File batches are executed synchronously,\nso this endpoint returns a \"completed\" or \"failed\" status.", "operationId": "vector_store_file_batch_get", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "batch_id", "in": "path", "description": "File batch ID", "required": true, "schema": { "type": "string" } } ], "responses": { "404": { "description": "File batches are not persisted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "delete": { "tags": [ "vector-stores" ], "summary": "Cancel a file batch", "description": "Cancels a file batch. Note: File batches are executed synchronously,\nso cancellation is not supported.", "operationId": "vector_store_file_batch_cancel", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "batch_id", "in": "path", "description": "File batch ID", "required": true, "schema": { "type": "string" } } ], "responses": { "400": { "description": "File batches cannot be cancelled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/vector_stores/{vector_store_id}/file_batches/{batch_id}/files": { "get": { "tags": [ "vector-stores" ], "summary": "List files in a batch", "description": "Lists files in a file batch. Note: File batches are not persisted.", "operationId": "vector_store_file_batch_list_files", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "batch_id", "in": "path", "description": "File batch ID", "required": true, "schema": { "type": "string" } } ], "responses": { "404": { "description": "File batches are not persisted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/vector_stores/{vector_store_id}/files": { "get": { "tags": [ "vector-stores" ], "summary": "List vector store files", "description": "Returns a list of files in a vector store.", "operationId": "vector_store_file_list", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "limit", "in": "query", "description": "Maximum number of files to return (default: 20, max: 100)", "required": false, "schema": { "type": [ "integer", "null" ], "format": "int64", "maximum": 100, "minimum": 1 } }, { "name": "order", "in": "query", "description": "Sort order by `created_at` timestamp (default: desc)", "required": false, "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SortOrder" } ] } }, { "name": "after", "in": "query", "description": "Cursor for forward pagination. Returns results after this file ID.", "required": false, "schema": { "type": [ "string", "null" ] }, "example": "vsf_550e8400-e29b-41d4-a716-446655440000" }, { "name": "before", "in": "query", "description": "Cursor for backward pagination. Returns results before this file ID.", "required": false, "schema": { "type": [ "string", "null" ] }, "example": "vsf_550e8400-e29b-41d4-a716-446655440000" }, { "name": "filter", "in": "query", "description": "Filter by status (in_progress, completed, failed, cancelled)", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "List of files", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorStoreFileListResponse" } } } }, "404": { "description": "Vector store not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "post": { "tags": [ "vector-stores" ], "summary": "Create a vector store file", "description": "Adds a file to a vector store. The file must already exist in the Files API.\nProcessing will start automatically after the file is added.\n\n## Content Deduplication\n\nFiles are deduplicated by content hash (SHA-256). If a file with identical content\nalready exists in the vector store, the existing file is returned with status 200\ninstead of creating a duplicate. This is idempotent behavior—uploading the same\ncontent multiple times has no additional effect.\n\n## Embedding Model Validation\n\nThe gateway validates that its configured embedding model matches the vector store's\nembedding model before adding files. This prevents incompatible embeddings from being\nstored together. If there's a mismatch, a 409 Conflict error is returned with details\nabout the expected vs. configured models.\n\n- **201 Created**: New file added, processing started\n- **200 OK**: Duplicate content detected, existing file returned (no re-processing)\n- **409 Conflict**: Embedding model mismatch between gateway configuration and vector store", "operationId": "vector_store_file_create", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateVectorStoreFileRequest" } } }, "required": true }, "responses": { "200": { "description": "Duplicate content detected, existing file returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorStoreFile" } } } }, "201": { "description": "File added to vector store", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorStoreFile" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Vector store or file not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Embedding model mismatch", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "File search service not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/vector_stores/{vector_store_id}/files/{file_id}": { "get": { "tags": [ "vector-stores" ], "summary": "Get a vector store file", "description": "Retrieves a file from a vector store.", "operationId": "vector_store_file_get", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "file_id", "in": "path", "description": "Vector store file ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Vector store file details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorStoreFile" } } } }, "404": { "description": "Vector store or file not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] }, "delete": { "tags": [ "vector-stores" ], "summary": "Delete a vector store file", "description": "Removes a file from a vector store. This does not delete the underlying file\nfrom the Files API.", "operationId": "vector_store_file_delete", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "file_id", "in": "path", "description": "Vector store file ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "File removed from vector store", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeleteVectorStoreFileResponse" } } } }, "404": { "description": "Vector store or file not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/vector_stores/{vector_store_id}/files/{file_id}/chunks": { "get": { "tags": [ "vector-stores" ], "summary": "List chunks for a file [Hadrian Extension]", "description": "**Hadrian Extension** - This endpoint is not part of the standard OpenAI API.\n\nReturns all chunks that have been extracted and embedded from a file. Useful for debugging chunking behavior and verifying embeddings.", "operationId": "vector_store_file_chunks_list", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "file_id", "in": "path", "description": "Vector store file ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "List of chunks for the file", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChunkListResponse" } } } }, "404": { "description": "Vector store or file not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "File search not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/api/v1/vector_stores/{vector_store_id}/search": { "post": { "tags": [ "vector-stores" ], "summary": "Search vector store", "description": "Performs a semantic search against a vector store.\n\n**Hadrian Extensions:** The response schema includes additional fields not in the standard OpenAI API:\n- `chunk_id`, `vector_store_id`, `chunk_index` (debugging info)", "operationId": "vector_store_search", "parameters": [ { "name": "vector_store_id", "in": "path", "description": "Vector store ID", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorStoreSearchRequest" } } }, "required": true }, "responses": { "200": { "description": "Search results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VectorStoreSearchResponse" } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Vector store not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "503": { "description": "File search not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "security": [ { "api_key": [] } ] } }, "/auth/discover": { "get": { "tags": [ "auth" ], "summary": "Discover SSO configuration for an email address.", "description": "This endpoint allows the frontend to determine which IdP to use for login\nbased on the user's email domain. If the email domain matches an organization\nwith SSO configured, the response includes the organization details and IdP info.\n\nSSO is only available when the email domain has been verified via DNS TXT record.\nThe response includes domain verification status to help users understand why\nSSO may not be available.", "operationId": "auth_discover", "parameters": [ { "name": "email", "in": "query", "description": "Email address to discover SSO configuration for", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "SSO discovery result for the email domain", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DiscoverResponse" } } } }, "403": { "description": "No SSO configuration found for the domain", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal error (database / config)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/auth/me": { "get": { "tags": [ "auth" ], "summary": "Get current user identity.", "operationId": "auth_me", "responses": { "200": { "description": "Authenticated user identity", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeResponse" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/health": { "get": { "tags": [ "health" ], "summary": "Full health check with subsystem status.", "description": "Returns detailed status of all subsystems including database, cache, and secrets manager.\nUse this endpoint for comprehensive health monitoring and dashboards.", "operationId": "health_check", "responses": { "200": { "description": "Service is healthy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HealthStatus" } } } }, "503": { "description": "Service is unhealthy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HealthStatus" } } } } } } }, "/health/live": { "get": { "tags": [ "health" ], "summary": "Kubernetes liveness probe.", "description": "Returns 200 if the service is running. This endpoint should always succeed\nunless the service process is completely broken. Use this for Kubernetes\nliveness probes to detect and restart unhealthy pods.", "operationId": "health_liveness", "responses": { "200": { "description": "Service is alive" } } } }, "/health/ready": { "get": { "tags": [ "health" ], "summary": "Kubernetes readiness probe.", "description": "Returns 200 if the service is ready to accept traffic. Checks that critical\ndependencies (database) are available. Use this for Kubernetes readiness\nprobes to control traffic routing to pods.", "operationId": "health_readiness", "responses": { "200": { "description": "Service is ready to accept traffic" }, "503": { "description": "Service is not ready (database unavailable)" } } } }, "/oauth/token": { "post": { "tags": [ "oauth" ], "summary": "Exchange a PKCE authorization code for a user-scoped API key.", "operationId": "oauth_token", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExchangeCodeForKey" } } }, "required": true }, "responses": { "200": { "description": "API key issued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OAuthTokenResponse" } } } }, "400": { "description": "Authorization code is invalid, expired, or already used", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "OAuth PKCE flow is disabled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } } }, "components": { "schemas": { "AccessGrantHistoryEntry": { "type": "object", "description": "Access grant history entry from audit logs", "required": [ "log_id", "action", "resource_type", "resource_id", "actor_type", "timestamp" ], "properties": { "action": { "type": "string", "description": "Action performed (e.g., \"org_membership.create\", \"project_membership.create\")" }, "actor_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Actor ID (if available)" }, "actor_type": { "type": "string", "description": "Actor type who performed the action" }, "details": { "description": "Additional details" }, "log_id": { "type": "string", "format": "uuid", "description": "Audit log ID" }, "resource_id": { "type": "string", "format": "uuid", "description": "Resource ID" }, "resource_type": { "type": "string", "description": "Resource type" }, "timestamp": { "type": "string", "format": "date-time", "description": "When the action occurred" } } }, "AccessInventoryQuery": { "type": "object", "description": "Query parameters for access inventory endpoint", "properties": { "format": { "$ref": "#/components/schemas/ExportFormat", "description": "Export format (json or csv)" }, "limit": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum number of users to return (default: 100, max: 1000)" }, "offset": { "type": [ "integer", "null" ], "format": "int64", "description": "Offset for pagination" }, "org_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Filter by organization ID" } } }, "AccessInventoryResponse": { "type": "object", "description": "Full access inventory response", "required": [ "generated_at", "total_users", "users", "summary" ], "properties": { "generated_at": { "type": "string", "format": "date-time", "description": "When this inventory was generated" }, "summary": { "$ref": "#/components/schemas/AccessInventorySummary", "description": "Summary statistics" }, "total_users": { "type": "integer", "format": "int64", "description": "Total number of users in the system" }, "users": { "type": "array", "items": { "$ref": "#/components/schemas/UserAccessInventoryEntry" }, "description": "Users with their access inventory" } } }, "AccessInventorySummary": { "type": "object", "description": "Summary statistics for the access inventory", "required": [ "total_organizations", "total_projects", "total_org_memberships", "total_project_memberships", "total_active_api_keys" ], "properties": { "total_active_api_keys": { "type": "integer", "format": "int64", "description": "Total number of active API keys" }, "total_org_memberships": { "type": "integer", "format": "int64", "description": "Total number of org memberships" }, "total_organizations": { "type": "integer", "format": "int64", "description": "Total number of organizations" }, "total_project_memberships": { "type": "integer", "format": "int64", "description": "Total number of project memberships" }, "total_projects": { "type": "integer", "format": "int64", "description": "Total number of projects" } } }, "AddMemberRequest": { "type": "object", "description": "Request to add a member to an organization or project", "required": [ "user_id" ], "properties": { "role": { "type": "string", "description": "Role to assign (defaults to 'member')" }, "user_id": { "type": "string", "format": "uuid", "description": "User ID to add as member" } } }, "AddTeamMember": { "type": "object", "description": "Request to add a member to a team", "required": [ "user_id" ], "properties": { "role": { "type": "string", "description": "Role to assign (defaults to 'member')" }, "source": { "$ref": "#/components/schemas/MembershipSource", "description": "Source of this membership (defaults to 'manual' for API calls)" }, "user_id": { "type": "string", "format": "uuid", "description": "User ID to add to the team" } } }, "ApiKey": { "type": "object", "required": [ "id", "key_prefix", "name", "owner", "created_at" ], "properties": { "allowed_models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Allowed models (null = all models, supports wildcards like \"gpt-4*\")" }, "budget_limit_cents": { "type": [ "integer", "null" ], "format": "int64", "description": "Budget limit in cents" }, "budget_period": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/BudgetPeriod" } ] }, "created_at": { "type": "string", "format": "date-time" }, "expires_at": { "type": [ "string", "null" ], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "ip_allowlist": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "IP allowlist in CIDR notation (null = all IPs allowed)" }, "key_prefix": { "type": "string", "description": "Prefix of the key (for identification without exposing full key)" }, "last_used_at": { "type": [ "string", "null" ], "format": "date-time" }, "name": { "type": "string" }, "owner": { "$ref": "#/components/schemas/ApiKeyOwner" }, "rate_limit_rpm": { "type": [ "integer", "null" ], "format": "int32", "description": "Requests per minute override (null = use global default)" }, "rate_limit_tpm": { "type": [ "integer", "null" ], "format": "int32", "description": "Tokens per minute override (null = use global default)" }, "revoked_at": { "type": [ "string", "null" ], "format": "date-time" }, "rotated_from_key_id": { "type": [ "string", "null" ], "format": "uuid", "description": "ID of the key this was rotated from (for audit trail)" }, "rotation_grace_until": { "type": [ "string", "null" ], "format": "date-time", "description": "If set, this key is being rotated out but still valid until this time" }, "scopes": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Permission scopes (null = full access)\nValid scopes: chat, completions, embeddings, images, audio, files, models, admin" }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "Sovereignty requirements that restrict which models this key can access" } ] } } }, "ApiKeyListResponse": { "type": "object", "description": "Paginated list of API keys", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/ApiKey" }, "description": "List of API keys" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "ApiKeyOwner": { "oneOf": [ { "type": "object", "required": [ "org_id", "type" ], "properties": { "org_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "organization" ] } } }, { "type": "object", "required": [ "team_id", "type" ], "properties": { "team_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "team" ] } } }, { "type": "object", "required": [ "project_id", "type" ], "properties": { "project_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "project" ] } } }, { "type": "object", "required": [ "user_id", "type" ], "properties": { "type": { "type": "string", "enum": [ "user" ] }, "user_id": { "type": "string", "format": "uuid" } } }, { "type": "object", "required": [ "service_account_id", "type" ], "properties": { "service_account_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "service_account" ] } } } ], "description": "Owner of an API key" }, "ApiKeyScope": { "type": "string", "description": "Permission scope for API keys.\n\nScopes control which API endpoints an API key can access.\nWhen `scopes` is `None` on an API key, the key has full access.\nWhen `scopes` is set, the key can only access endpoints matching those scopes.", "enum": [ "chat", "completions", "embeddings", "images", "audio", "files", "models", "admin" ] }, "ApiKeySummary": { "type": "object", "description": "Summary of API key ownership for a user", "required": [ "active_count", "revoked_count", "expired_count", "total_count" ], "properties": { "active_count": { "type": "integer", "format": "int64", "description": "Number of active API keys owned by the user" }, "expired_count": { "type": "integer", "format": "int64", "description": "Number of expired API keys owned by the user" }, "revoked_count": { "type": "integer", "format": "int64", "description": "Number of revoked API keys owned by the user" }, "total_count": { "type": "integer", "format": "int64", "description": "Total number of API keys" } } }, "AppendMessages": { "type": "object", "description": "Request to append messages to a conversation", "required": [ "messages" ], "properties": { "messages": { "type": "array", "items": { "$ref": "#/components/schemas/Message" } } } }, "AttributeFilter": { "oneOf": [ { "$ref": "#/components/schemas/ComparisonFilter", "description": "A simple comparison filter" }, { "$ref": "#/components/schemas/CompoundFilter", "description": "A compound filter combining multiple filters" } ], "description": "A filter for attribute-based search filtering.\n\nThis is a union type that can be either a [`ComparisonFilter`] for simple\ncomparisons or a [`CompoundFilter`] for combining multiple filters.\n\n# Deserialization\n\nThe filter type is determined by the `type` field:\n- `eq`, `ne`, `gt`, `gte`, `lt`, `lte` → [`ComparisonFilter`]\n- `and`, `or` → [`CompoundFilter`]\n\n# Example: Simple comparison\n\n```json\n{ \"type\": \"eq\", \"key\": \"status\", \"value\": \"published\" }\n```\n\n# Example: Compound filter\n\n```json\n{\n \"type\": \"and\",\n \"filters\": [\n { \"type\": \"gte\", \"key\": \"date\", \"value\": 1704067200 },\n { \"type\": \"lte\", \"key\": \"date\", \"value\": 1706745600 }\n ]\n}\n```" }, "AudioResponseFormat": { "type": "string", "description": "Response format for transcription/translation.", "enum": [ "json", "text", "srt", "verbose_json", "vtt", "diarized_json" ] }, "AuditActorType": { "type": "string", "description": "Type of actor that performed an action", "enum": [ "user", "api_key", "service_account", "external_user", "system" ] }, "AuditLog": { "type": "object", "description": "An audit log entry recording an admin operation", "required": [ "id", "timestamp", "actor_type", "action", "resource_type", "resource_id", "details" ], "properties": { "action": { "type": "string", "description": "The action performed (e.g., \"api_key.create\", \"user.update\")" }, "actor_id": { "type": [ "string", "null" ], "format": "uuid", "description": "ID of the actor (user_id or api_key_id, None for system)" }, "actor_type": { "$ref": "#/components/schemas/AuditActorType", "description": "Type of actor that performed the action" }, "details": { "$ref": "#/components/schemas/Value", "description": "Additional details as JSON" }, "id": { "type": "string", "format": "uuid", "description": "Unique identifier for this audit log entry" }, "ip_address": { "type": [ "string", "null" ], "description": "Client IP address" }, "org_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Organization context (if applicable)" }, "project_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Project context (if applicable)" }, "resource_id": { "type": "string", "format": "uuid", "description": "ID of the affected resource" }, "resource_type": { "type": "string", "description": "Type of resource affected (e.g., \"api_key\", \"user\", \"organization\")" }, "timestamp": { "type": "string", "format": "date-time", "description": "When the action occurred" }, "user_agent": { "type": [ "string", "null" ], "description": "Client user agent" } } }, "AuditLogListResponse": { "type": "object", "description": "Paginated list of audit logs", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/AuditLog" }, "description": "List of audit log entries" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "AuditLogQuery": { "type": "object", "description": "Query parameters for listing audit logs", "properties": { "action": { "type": [ "string", "null" ], "description": "Filter by action (e.g., \"api_key.create\")" }, "actor_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Filter by actor ID" }, "actor_type": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AuditActorType", "description": "Filter by actor type" } ] }, "cursor": { "type": [ "string", "null" ], "description": "Cursor for pagination (cursor-based pagination)", "example": "MTczMzU4MDgwMDAwMDphYmMxMjM0NS02Nzg5LTAxMjMtNDU2Ny0wMTIzNDU2Nzg5YWI" }, "direction": { "type": [ "string", "null" ], "description": "Pagination direction (forward or backward). Only used with cursor." }, "from": { "type": [ "string", "null" ], "format": "date-time", "description": "Start of time range (inclusive)" }, "limit": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum number of results to return" }, "org_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Filter by organization ID" }, "project_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Filter by project ID" }, "resource_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Filter by resource ID" }, "resource_type": { "type": [ "string", "null" ], "description": "Filter by resource type (e.g., \"api_key\")" }, "to": { "type": [ "string", "null" ], "format": "date-time", "description": "End of time range (exclusive)" } } }, "AuthorizationCodeResponse": { "type": "object", "description": "Response from `POST /admin/v1/oauth/authorize` after consent.", "required": [ "code", "redirect_url", "expires_at" ], "properties": { "code": { "type": "string", "description": "Authorization code to forward to the external app via `callback_url?code=...`." }, "expires_at": { "type": "string", "format": "date-time", "description": "When the code expires; the exchange must complete before this time." }, "redirect_url": { "type": "string", "description": "Fully-formed redirect URL (callback_url with the `code` query parameter)." } } }, "AuthorizationServerMetadata": { "type": "object", "description": "Authorization Server Metadata document per\n[RFC 8414](https://www.rfc-editor.org/rfc/rfc8414). Lets PKCE clients\ndiscover Hadrian's authorize/token endpoints, supported challenge\nmethods, and supported scopes without hard-coding URLs.\n\nHadrian implements only the subset of OAuth 2.0 needed for the PKCE\nauthorization-code flow: there is no dynamic client registration, no\nrefresh tokens, and no client credentials grant. Fields the spec marks\nas required but that are not meaningful for our flow are emitted with\nthe closest accurate value (e.g. `token_endpoint_auth_methods_supported`\nis `[\"none\"]` because clients authenticate via PKCE proof, not a secret).", "required": [ "issuer", "authorization_endpoint", "token_endpoint", "code_challenge_methods_supported", "response_types_supported", "grant_types_supported", "token_endpoint_auth_methods_supported", "scopes_supported" ], "properties": { "authorization_endpoint": { "type": "string", "description": "URL of the authorization (consent) endpoint." }, "code_challenge_methods_supported": { "type": "array", "items": { "type": "string" }, "description": "PKCE challenge methods supported by this server." }, "grant_types_supported": { "type": "array", "items": { "type": "string" }, "description": "OAuth 2.0 grant types supported. Always `[\"authorization_code\"]`." }, "issuer": { "type": "string", "description": "Issuer identifier — the deployment's base URL." }, "response_types_supported": { "type": "array", "items": { "type": "string" }, "description": "OAuth 2.0 response types supported. Always `[\"code\"]`." }, "scopes_supported": { "type": "array", "items": { "type": "string" }, "description": "API-key scopes that may appear in `scopes` on the authorize request." }, "service_documentation": { "type": [ "string", "null" ], "description": "Whether the server provides a metadata document (always true here —\nincluded for clients that probe the field)." }, "token_endpoint": { "type": "string", "description": "URL of the token (code-exchange) endpoint." }, "token_endpoint_auth_methods_supported": { "type": "array", "items": { "type": "string" }, "description": "Token endpoint client-authentication methods. Always `[\"none\"]` —\nPKCE is the authentication mechanism." } } }, "BudgetPeriod": { "type": "string", "description": "Budget period for spending limits", "enum": [ "daily", "monthly" ] }, "BuiltInProvider": { "type": "object", "description": "Built-in provider summary", "required": [ "name", "provider_type" ], "properties": { "base_url": { "type": [ "string", "null" ], "description": "Base URL (if applicable)" }, "name": { "type": "string", "description": "Provider name (as configured in hadrian.toml)" }, "provider_type": { "type": "string", "description": "Provider type (e.g., \"open_ai\", \"anthropic\")" } } }, "BuiltInProvidersResponse": { "type": "object", "description": "List of built-in providers from the gateway configuration", "required": [ "data" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/BuiltInProvider" } } } }, "BulkUpsertResponse": { "type": "object", "description": "Response for bulk upsert operation", "required": [ "count" ], "properties": { "count": { "type": "integer", "description": "Number of entries upserted", "minimum": 0 } } }, "CacheControl": { "type": "object", "description": "Cache control configuration for prompt caching\n\n**Hadrian Extension:** This field is not part of the OpenAI API specification.\nIt is a Hadrian-specific extension to support Anthropic and Bedrock prompt caching.\n\nWhen present on content blocks or tools, it signals that the content up to this\npoint should be cached for future requests:\n- **Anthropic:** Passed through as `cache_control: { type: \"ephemeral\" }`\n- **Bedrock:** Transformed into `cachePoint` blocks after the content\n- **OpenAI/Azure:** Ignored (these providers use automatic caching)", "required": [ "type" ], "properties": { "type": { "$ref": "#/components/schemas/CacheControlType", "description": "The type of cache control" } } }, "CacheControlType": { "type": "string", "description": "Cache control type for prompt caching\n\n**Hadrian Extension:** This field is not part of the OpenAI API specification.\nIt is a Hadrian-specific extension to support Anthropic and Bedrock prompt caching.", "enum": [ "ephemeral" ] }, "ChunkListResponse": { "type": "object", "description": "Paginated list of chunks response", "required": [ "object", "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/ChunkResponse" }, "description": "List of chunks" }, "object": { "type": "string", "description": "Object type (always \"list\")" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "ChunkResponse": { "type": "object", "description": "A stored chunk as returned by the chunks endpoint.\n\n## OpenAI Compatibility Notes\n\n- `id` is serialized with `chunk_` prefix (e.g., `chunk_550e8400-e29b-41d4-a716-446655440000`)\n- `vector_store_id` is serialized with `vs_` prefix\n- `file_id` is serialized with `file-` prefix", "required": [ "id", "object", "vector_store_id", "file_id", "chunk_index", "content", "token_count", "char_start", "char_end", "created_at" ], "properties": { "char_end": { "type": "integer", "format": "int32", "description": "Character offset where this chunk ends in the original file" }, "char_start": { "type": "integer", "format": "int32", "description": "Character offset where this chunk starts in the original file" }, "chunk_index": { "type": "integer", "format": "int32", "description": "Sequential index within the file (0-based)" }, "content": { "type": "string", "description": "The actual text content of the chunk" }, "created_at": { "type": "integer", "format": "int64", "description": "Unix timestamp when the chunk was created" }, "file_id": { "type": "string", "description": "The file this chunk was extracted from (serialized with `file-` prefix)", "example": "file-550e8400-e29b-41d4-a716-446655440000" }, "id": { "type": "string", "description": "Unique identifier for this chunk (serialized with `chunk_` prefix)", "example": "chunk_550e8400-e29b-41d4-a716-446655440000" }, "metadata": { "description": "Optional additional metadata" }, "object": { "type": "string", "description": "Object type (always \"vector_store.file.chunk\")" }, "token_count": { "type": "integer", "format": "int32", "description": "Number of tokens in this chunk" }, "vector_store_id": { "type": "string", "description": "The vector store this chunk belongs to (serialized with `vs_` prefix)", "example": "vs_550e8400-e29b-41d4-a716-446655440000" } } }, "ChunkingStrategy": { "oneOf": [ { "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "auto" ] } } }, { "type": "object", "required": [ "static", "type" ], "properties": { "static": { "$ref": "#/components/schemas/StaticChunkingConfig" }, "type": { "type": "string", "enum": [ "static" ] } } } ], "description": "Chunking strategy configuration (OpenAI-compatible)\nOpenAI schema: {\"type\": \"auto\"} or {\"type\": \"static\", \"static\": {...}}" }, "CircuitBreakerStatus": { "type": "object", "description": "Status of a circuit breaker for API responses.", "required": [ "provider", "state", "failure_count" ], "properties": { "failure_count": { "type": "integer", "format": "int32", "description": "Number of consecutive failures (only relevant in Closed state).", "example": 0, "minimum": 0 }, "provider": { "type": "string", "description": "Provider name." }, "state": { "$ref": "#/components/schemas/CircuitState", "description": "Current state (closed, open, or half_open)." } } }, "CircuitBreakersResponse": { "type": "object", "description": "Response for circuit breaker status endpoint.", "required": [ "circuit_breakers" ], "properties": { "circuit_breakers": { "type": "array", "items": { "$ref": "#/components/schemas/CircuitBreakerStatus" }, "description": "List of circuit breaker statuses for all providers." } } }, "CircuitState": { "type": "string", "description": "Circuit breaker state.", "enum": [ "closed", "open", "half_open" ] }, "CombinedModelsResponse": { "type": "object", "description": "Combined models response with provider-prefixed model IDs.", "required": [ "data" ], "properties": { "data": { "type": "array", "items": { "type": "object" }, "description": "List of available models" } } }, "CompactRequest": { "type": "object", "description": "Request body for `POST /v1/responses/compact`.\n\nMirrors OpenAI's `CompactResponseMethodPublicBody`: `model` is\nrequired; everything else is optional. Hadrian-specific extensions\n(`models`, `stream`, `sovereignty_requirements`) ride alongside\nbecause the gateway still routes, streams, and enforces sovereignty\nfor compaction requests just like the main `/responses` handler.", "required": [ "model" ], "properties": { "input": { "type": "object", "description": "Conversation history to compact. Accepts a plain string or the\ntyped item array used by `POST /responses`." }, "instructions": { "type": [ "string", "null" ], "description": "System instructions threaded into the compaction prompt." }, "model": { "type": "string", "description": "Model to compact with. Required by OpenAI; Hadrian also accepts\nit as the routing key when the gateway picks an upstream\nprovider." }, "models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "**Hadrian Extension:** alternate model list for multi-model\nrouting. The first entry the gateway resolves successfully wins." }, "previous_response_id": { "type": [ "string", "null" ], "description": "Continue compacting from a previously persisted response. Spec:\n`CompactResponseMethodPublicBody.previous_response_id`." }, "prompt_cache_key": { "type": [ "string", "null" ], "description": "OpenAI prompt-cache key passthrough." }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "**Hadrian Extension:** per-request data-sovereignty requirements.\nMerged with API-key-level requirements; the most restrictive\nwins." } ] }, "stream": { "type": "boolean", "description": "**Hadrian Extension:** stream the compacted response as SSE.\nForwarded verbatim to the upstream provider when supported." } } }, "ComparisonFilter": { "type": "object", "description": "A comparison filter for attribute-based filtering.\n\nCompares a specific attribute key to a given value using a comparison operator.\n\n# Example\n\n```json\n{\n \"type\": \"eq\",\n \"key\": \"author\",\n \"value\": \"John Doe\"\n}\n```\n\n# Supported Comparisons\n\n| Operator | Description |\n|----------|-------------|\n| `eq` | Equal to |\n| `ne` | Not equal to |\n| `gt` | Greater than |\n| `gte` | Greater than or equal to |\n| `lt` | Less than |\n| `lte` | Less than or equal to |", "required": [ "type", "key", "value" ], "properties": { "key": { "type": "string", "description": "The attribute key to compare." }, "type": { "$ref": "#/components/schemas/ComparisonOperator", "description": "The comparison operator to use." }, "value": { "$ref": "#/components/schemas/FilterValue", "description": "The value to compare against." } } }, "ComparisonOperator": { "type": "string", "description": "Comparison operators for attribute filtering.\n\nThese operators compare an attribute's value against a target value.", "enum": [ "eq", "ne", "gt", "gte", "lt", "lte" ] }, "ComponentStatus": { "type": "object", "description": "Status of a single component.", "required": [ "healthy" ], "properties": { "healthy": { "type": "boolean", "description": "Whether the component is healthy", "example": true }, "latency_ms": { "type": [ "integer", "null" ], "format": "int64", "description": "Latency of the health check in milliseconds", "example": 5, "minimum": 0 }, "message": { "type": [ "string", "null" ], "description": "Optional message with details", "example": null } } }, "CompoundFilter": { "type": "object", "description": "A compound filter that combines multiple filters with logical operators.\n\nAllows building complex filter expressions by combining comparison filters\nand/or other compound filters using `and` or `or` logic.\n\n# Example\n\n```json\n{\n \"type\": \"and\",\n \"filters\": [\n { \"type\": \"eq\", \"key\": \"category\", \"value\": \"documentation\" },\n {\n \"type\": \"or\",\n \"filters\": [\n { \"type\": \"eq\", \"key\": \"author\", \"value\": \"Alice\" },\n { \"type\": \"eq\", \"key\": \"author\", \"value\": \"Bob\" }\n ]\n }\n ]\n}\n```", "required": [ "type", "filters" ], "properties": { "filters": { "type": "array", "items": { "$ref": "#/components/schemas/AttributeFilter" }, "description": "The filters to combine." }, "type": { "$ref": "#/components/schemas/LogicalOperator", "description": "The logical operator (`and` or `or`)." } } }, "ConnectivityTestResponse": { "type": "object", "description": "Result of a provider connectivity test", "required": [ "status", "message" ], "properties": { "latency_ms": { "type": [ "integer", "null" ], "format": "int64", "description": "Latency in milliseconds", "minimum": 0 }, "message": { "type": "string", "description": "Human-readable message" }, "status": { "type": "string", "description": "Whether the test was successful" } } }, "ContainerExpiresAfter": { "type": "object", "description": "Container TTL hint. Mirrors OpenAI's `expires_after` shape — only\n`last_active_at` is honored today (the same anchor the operator's\nidle reaper uses), with `minutes` setting the per-container idle\nTTL.", "required": [ "minutes" ], "properties": { "anchor": { "$ref": "#/components/schemas/ContainerExpiresAfterAnchor", "description": "Anchor for the TTL countdown. Today only `\"last_active_at\"` is\nsupported; unknown anchors reject with 400." }, "minutes": { "type": "integer", "format": "int32", "description": "Minutes after `anchor` when the container expires. Validated\nagainst `[features.containers].max_idle_ttl_secs / 60`.", "minimum": 0 } }, "additionalProperties": false }, "ContainerExpiresAfterAnchor": { "type": "string", "enum": [ "last_active_at" ] }, "ContentPart": { "oneOf": [ { "type": "object", "required": [ "text", "type" ], "properties": { "cache_control": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CacheControl", "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" } ] }, "text": { "type": "string" }, "type": { "type": "string", "enum": [ "text" ] } } }, { "type": "object", "required": [ "image_url", "type" ], "properties": { "cache_control": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CacheControl", "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" } ] }, "image_url": { "$ref": "#/components/schemas/ImageUrl" }, "type": { "type": "string", "enum": [ "image_url" ] } } }, { "type": "object", "required": [ "input_audio", "type" ], "properties": { "cache_control": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CacheControl", "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" } ] }, "input_audio": { "$ref": "#/components/schemas/InputAudio" }, "type": { "type": "string", "enum": [ "input_audio" ] } } }, { "type": "object", "required": [ "video_url", "type" ], "properties": { "cache_control": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CacheControl", "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" } ] }, "type": { "type": "string", "enum": [ "input_video" ] }, "video_url": { "$ref": "#/components/schemas/VideoUrl" } } }, { "type": "object", "required": [ "video_url", "type" ], "properties": { "cache_control": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CacheControl", "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" } ] }, "type": { "type": "string", "enum": [ "video_url" ] }, "video_url": { "$ref": "#/components/schemas/VideoUrl" } } } ], "description": "Content part for multimodal messages" }, "Conversation": { "type": "object", "description": "A conversation storing chat message history", "required": [ "id", "owner_type", "owner_id", "title", "messages", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "messages": { "type": "array", "items": { "$ref": "#/components/schemas/Message" } }, "models": { "type": "array", "items": { "type": "string" }, "description": "Models used in this conversation" }, "owner_id": { "type": "string", "format": "uuid" }, "owner_type": { "$ref": "#/components/schemas/ConversationOwnerType" }, "pin_order": { "type": [ "integer", "null" ], "format": "int32", "description": "Pin order for the conversation. NULL = not pinned, 0-N = pinned with order (lower = higher in list)" }, "title": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ConversationListResponse": { "type": "object", "description": "Paginated list of conversations", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Conversation" }, "description": "List of conversations" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "ConversationOwner": { "oneOf": [ { "type": "object", "required": [ "project_id", "type" ], "properties": { "project_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "project" ] } } }, { "type": "object", "required": [ "user_id", "type" ], "properties": { "type": { "type": "string", "enum": [ "user" ] }, "user_id": { "type": "string", "format": "uuid" } } } ], "description": "Owner specification for creating a conversation" }, "ConversationOwnerType": { "type": "string", "description": "Owner type for conversations", "enum": [ "project", "user" ] }, "ConversationWithProject": { "allOf": [ { "$ref": "#/components/schemas/Conversation" }, { "type": "object", "properties": { "project_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Project ID if this conversation belongs to a project" }, "project_name": { "type": [ "string", "null" ], "description": "Project name for display" }, "project_slug": { "type": [ "string", "null" ], "description": "Project slug for URL construction" } } } ], "description": "A conversation with optional project metadata\n\nUsed when listing conversations that may belong to a project,\nso that the client can display project context." }, "ConversationWithProjectListResponse": { "type": "object", "description": "List of conversations with project metadata", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/ConversationWithProject" }, "description": "List of conversations with project info" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "CostForecastResponse": { "type": "object", "description": "Cost forecast response", "required": [ "current_spend", "avg_daily_spend", "std_dev_daily_spend", "sample_days" ], "properties": { "avg_daily_spend": { "type": "number", "format": "double", "description": "Average daily spend (dollars) based on historical data" }, "budget_limit": { "type": [ "number", "null" ], "format": "double", "description": "Budget limit (dollars), null if no budget configured" }, "budget_period": { "type": [ "string", "null" ], "description": "Budget period (daily or monthly)" }, "budget_utilization_percent": { "type": [ "number", "null" ], "format": "double", "description": "Percentage of budget used in current period" }, "current_spend": { "type": "number", "format": "double", "description": "Current spend in the budget period (dollars)" }, "days_until_exhaustion": { "type": [ "number", "null" ], "format": "double", "description": "Projected days until budget exhaustion (null if no budget or zero spend rate)" }, "days_until_exhaustion_lower": { "type": [ "number", "null" ], "format": "double", "description": "Lower bound days until exhaustion (95% confidence, assumes +1 std dev spend)" }, "days_until_exhaustion_upper": { "type": [ "number", "null" ], "format": "double", "description": "Upper bound days until exhaustion (95% confidence, assumes -1 std dev spend)" }, "projected_exhaustion_date": { "type": [ "string", "null" ], "description": "Projected exhaustion date (YYYY-MM-DD, null if no budget or zero spend rate)" }, "projected_period_spend": { "type": [ "number", "null" ], "format": "double", "description": "Projected end-of-period spend at current rate (dollars)" }, "sample_days": { "type": "integer", "format": "int32", "description": "Number of days of historical data used" }, "std_dev_daily_spend": { "type": "number", "format": "double", "description": "Standard deviation of daily spend (dollars)" }, "time_series_forecast": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/TimeSeriesForecastResponse", "description": "Time series forecast with prediction intervals (null if insufficient data)" } ] } } }, "CreateApiKey": { "type": "object", "required": [ "name", "owner" ], "properties": { "allowed_models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Allowed models (null = all models)" }, "budget_limit_cents": { "type": [ "integer", "null" ], "format": "int64", "description": "Budget limit in cents" }, "budget_period": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/BudgetPeriod" } ] }, "expires_at": { "type": [ "string", "null" ], "format": "date-time" }, "ip_allowlist": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "IP allowlist in CIDR notation (null = all IPs)" }, "name": { "type": "string" }, "owner": { "$ref": "#/components/schemas/ApiKeyOwner" }, "rate_limit_rpm": { "type": [ "integer", "null" ], "format": "int32", "description": "Requests per minute override" }, "rate_limit_tpm": { "type": [ "integer", "null" ], "format": "int32", "description": "Tokens per minute override" }, "scopes": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Permission scopes (null = full access)" }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "Sovereignty requirements for model access" } ] } } }, "CreateAuthorizationCode": { "type": "object", "description": "Request body for `POST /admin/v1/oauth/authorize` — issued by the\nauthenticated user from the consent page after they click \"Allow\".", "required": [ "callback_url", "code_challenge", "code_challenge_method" ], "properties": { "app_name": { "type": [ "string", "null" ], "description": "Optional human-readable name of the requesting app, shown on the consent screen." }, "callback_url": { "type": "string", "description": "Where the external app expects the user to land after consent.\nThe exchange endpoint requires this exact same value when redeeming." }, "code_challenge": { "type": "string", "description": "PKCE challenge supplied by the external app. RFC 7636 §4.1 mandates\n43–128 characters for both the verifier and (by extension) the\n`S256` / `plain` challenges." }, "code_challenge_method": { "$ref": "#/components/schemas/PkceCodeChallengeMethod", "description": "Method used to derive the challenge. `S256` unless `auth.oauth_pkce.allow_plain_method` is set." }, "key_options": { "$ref": "#/components/schemas/OAuthKeyOptions", "description": "User's choices for the API key that will be issued on exchange.\nMirrors the fields shown in the self-service \"Create API Key\" modal." } } }, "CreateChatCompletionPayload": { "type": "object", "description": "Create chat completion request (OpenAI-compatible)", "required": [ "messages" ], "properties": { "frequency_penalty": { "type": [ "number", "null" ], "format": "double", "description": "Penalize repeated tokens (-2.0 to 2.0)" }, "logit_bias": { "type": "object", "description": "Token bias map" }, "logprobs": { "type": [ "boolean", "null" ], "description": "Return log probabilities" }, "max_completion_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum completion tokens", "minimum": 0 }, "max_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum tokens (deprecated, use max_completion_tokens)", "minimum": 0 }, "messages": { "type": "array", "items": { "$ref": "#/components/schemas/Message" }, "description": "Conversation messages" }, "metadata": { "type": "object", "description": "Request metadata" }, "model": { "type": [ "string", "null" ], "description": "Model to use for completion" }, "models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "**Hadrian Extension:** List of models for multi-model routing (alternative to single model)" }, "presence_penalty": { "type": [ "number", "null" ], "format": "double", "description": "Penalize new topics (-2.0 to 2.0)" }, "reasoning": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CreateChatCompletionReasoning", "description": "**Hadrian Extension:** Reasoning/extended thinking configuration (Anthropic, O1/O3 models)" } ] }, "response_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ResponseFormat", "description": "Output format" } ] }, "seed": { "type": [ "integer", "null" ], "format": "int64", "description": "Random seed for reproducibility" }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "**Hadrian Extension:** Per-request sovereignty requirements.\nMerged with API key requirements (most restrictive wins)." } ] }, "stop": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/Stop", "description": "Stop sequence(s)" } ] }, "stream": { "type": "boolean", "description": "Enable streaming" }, "stream_options": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/StreamOptions", "description": "Stream options" } ] }, "temperature": { "type": [ "number", "null" ], "format": "double", "description": "Sampling temperature (0.0 to 2.0)" }, "tool_choice": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ToolChoice", "description": "Tool choice configuration" } ] }, "tools": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/ToolDefinition" }, "description": "Available tools" }, "top_logprobs": { "type": [ "integer", "null" ], "format": "int32", "description": "Number of top log probabilities to return (0-20)", "minimum": 0 }, "top_p": { "type": [ "number", "null" ], "format": "double", "description": "Nucleus sampling probability (0.0 to 1.0)" }, "user": { "type": [ "string", "null" ], "description": "User identifier for abuse detection" } } }, "CreateChatCompletionReasoning": { "type": "object", "description": "Reasoning configuration for chat completion", "properties": { "effort": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ReasoningEffort" } ] }, "summary": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ReasoningSummary" } ] } } }, "CreateCompletionPayload": { "type": "object", "description": "Create text completion request (OpenAI-compatible)", "required": [ "prompt" ], "properties": { "best_of": { "type": [ "integer", "null" ], "format": "int64", "description": "Number of completions to generate and return the best" }, "echo": { "type": [ "boolean", "null" ], "description": "Echo the prompt in the response" }, "frequency_penalty": { "type": [ "number", "null" ], "format": "double", "description": "Penalize repeated tokens (-2.0 to 2.0)" }, "logit_bias": { "type": "object", "description": "Token bias map" }, "logprobs": { "type": [ "integer", "null" ], "format": "int64", "description": "Number of log probabilities to return" }, "max_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum tokens to generate" }, "metadata": { "type": "object", "description": "**Hadrian Extension:** Request metadata for tracking and filtering" }, "model": { "type": [ "string", "null" ], "description": "Model to use for completion" }, "models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "**Hadrian Extension:** List of models for multi-model routing (alternative to single model)" }, "n": { "type": [ "integer", "null" ], "format": "int64", "description": "Number of completions to generate" }, "presence_penalty": { "type": [ "number", "null" ], "format": "double", "description": "Penalize new topics (-2.0 to 2.0)" }, "prompt": { "type": "object", "description": "The prompt to generate completions for" }, "response_format": { "type": "object", "description": "**Hadrian Extension:** Response format (OpenAI only supports this on chat/completions)" }, "seed": { "type": [ "integer", "null" ], "format": "int64", "description": "Random seed for reproducibility" }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "**Hadrian Extension:** Per-request sovereignty requirements.\nMerged with API key requirements (most restrictive wins)." } ] }, "stop": { "type": "object", "description": "Stop sequence(s)" }, "stream": { "type": "boolean", "description": "Enable streaming" }, "stream_options": { "type": "object", "description": "Stream options" }, "suffix": { "type": [ "string", "null" ], "description": "Text to append after completion" }, "temperature": { "type": [ "number", "null" ], "format": "double", "description": "Sampling temperature (0.0 to 2.0)" }, "top_p": { "type": [ "number", "null" ], "format": "double", "description": "Nucleus sampling probability (0.0 to 1.0)" }, "user": { "type": [ "string", "null" ], "description": "User identifier for abuse detection" } } }, "CreateContainerRequest": { "type": "object", "description": "Request body for `POST /v1/containers`.", "properties": { "expires_after": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ContainerExpiresAfter", "description": "Optional idle-TTL hint. Per OpenAI's spec: `{anchor:\n\"last_active_at\", minutes: N}`. Capped by\n`[features.containers].max_idle_ttl_secs / 60`." } ] }, "file_ids": { "type": "array", "items": { "type": "string" }, "description": "Files-API ids to copy into `/mnt/data` at container creation.\nSpec: `CreateContainerBody.file_ids`. Each id is resolved via\nthe Files API (same path as `input_file` parts on a response\nrequest) and the bytes are persisted into `container_files`\nso the model can read them on first attach." }, "memory_limit": { "type": [ "string", "null" ], "description": "Optional memory ceiling. Accepts OpenAI's `\"1g\"` / `\"512m\"`\nstrings; parsed case-insensitively. Capped by the operator's\n`[features.server_tools.shell_limits].max_mem_limit_mb`." }, "name": { "type": [ "string", "null" ], "description": "Optional display name (max 255 chars)." }, "network_policy": { "type": "object", "description": "Optional network policy (same shape as\n`tools.shell.environment.network_policy`). OpenAI types this as\na `oneOf { Disabled, Allowlist }` discriminated by `type`;\nHadrian represents it as a single flat object that validates\nthe same constraints at request resolution, so the schema is\nrendered as an opaque `object` to avoid spurious diffs." }, "skills": { "type": "array", "items": { "type": "object" }, "description": "Skills to mount whenever a session is booted against this\ncontainer. Matches OpenAI's typed shape — see\n[`crate::api_types::RequestSkill`]." } }, "additionalProperties": false }, "CreateConversation": { "type": "object", "description": "Request to create a new conversation", "required": [ "owner", "title" ], "properties": { "messages": { "type": "array", "items": { "$ref": "#/components/schemas/Message" }, "description": "Initial messages (optional)" }, "models": { "type": "array", "items": { "type": "string" }, "description": "Models used in this conversation" }, "owner": { "$ref": "#/components/schemas/ConversationOwner", "description": "Owner of the conversation" }, "title": { "type": "string", "description": "Title of the conversation" } } }, "CreateDomainVerification": { "type": "object", "description": "Request to initiate domain verification.", "required": [ "domain" ], "properties": { "domain": { "type": "string", "description": "The domain to verify (e.g., \"acme.com\")" } } }, "CreateDynamicProvider": { "type": "object", "required": [ "name", "owner", "provider_type" ], "properties": { "api_key": { "type": [ "string", "null" ], "description": "Raw API key (stored in secrets manager if available, otherwise stored directly)" }, "base_url": { "type": "string", "description": "Base URL for the provider (required for OpenAI/Anthropic/Azure, optional for Bedrock/Vertex)" }, "config": { "description": "Provider-specific configuration (e.g., region, credentials for Bedrock/Vertex)" }, "models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "List of supported model names" }, "name": { "type": "string" }, "owner": { "$ref": "#/components/schemas/ProviderOwner" }, "provider_type": { "type": "string", "description": "Provider type (e.g., \"open_ai\", \"anthropic\", \"bedrock\", \"vertex\")" }, "sovereignty": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyMetadata", "description": "Sovereignty and compliance metadata" } ] } } }, "CreateEmbeddingPayload": { "type": "object", "description": "Create embedding request (OpenAI-compatible)", "required": [ "input", "model" ], "properties": { "dimensions": { "type": [ "integer", "null" ], "format": "int64", "description": "Number of dimensions for output embeddings" }, "encoding_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/EncodingFormat", "description": "Output encoding format" } ] }, "input": { "$ref": "#/components/schemas/EmbeddingInput", "description": "Input to embed" }, "input_type": { "type": [ "string", "null" ], "description": "**Hadrian Extension:** Input type hint for embedding providers that support it (e.g., Cohere)" }, "model": { "type": "string", "description": "Model to use for embedding" }, "provider": { "type": "object", "description": "**Hadrian Extension:** Provider routing configuration" }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "**Hadrian Extension:** Per-request sovereignty requirements.\nMerged with API key requirements (most restrictive wins)." } ] }, "user": { "type": [ "string", "null" ], "description": "User identifier for abuse detection" } } }, "CreateFileBatchRequest": { "type": "object", "description": "Create file batch request", "required": [ "file_ids" ], "properties": { "chunking_strategy": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ChunkingStrategy", "description": "Chunking strategy for all files in the batch" } ] }, "file_ids": { "type": "array", "items": { "type": "string", "format": "uuid" }, "description": "File IDs to add to the batch" } } }, "CreateImageEditRequest": { "type": "object", "description": "Create image edit request (POST /v1/images/edits)\n\nNote: This endpoint accepts multipart/form-data. The `image` and `mask`\nfields are file uploads, not JSON fields.", "required": [ "prompt" ], "properties": { "background": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageBackground", "description": "Background transparency setting. GPT image models only." } ] }, "model": { "type": [ "string", "null" ], "description": "The model to use for image editing." }, "n": { "type": [ "integer", "null" ], "format": "int32", "description": "Number of images to generate (1-10)." }, "output_compression": { "type": [ "integer", "null" ], "format": "int32", "description": "Compression level (0-100%) for webp/jpeg output." }, "output_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageOutputFormat", "description": "Output format for GPT image models (png, jpeg, webp)." } ] }, "partial_images": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PartialImages", "description": "Partial images configuration for streaming." } ] }, "prompt": { "type": "string", "description": "A text description of the desired edit.\nMax 1000 chars for dall-e-2, 32000 for GPT image models." }, "quality": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageQuality", "description": "The quality of the generated image." } ] }, "response_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageResponseFormat", "description": "Format for returning generated images (url or b64_json)." } ] }, "size": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageSize", "description": "Size of the generated images." } ] }, "stream": { "type": [ "boolean", "null" ], "description": "Edit image in streaming mode. GPT image models only." }, "user": { "type": [ "string", "null" ], "description": "Unique identifier for the end-user for abuse detection." } } }, "CreateImageRequest": { "type": "object", "description": "Create image generation request (POST /v1/images/generations)", "required": [ "prompt" ], "properties": { "background": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageBackground", "description": "Background transparency setting. GPT image models only." } ] }, "model": { "type": [ "string", "null" ], "description": "The model to use for image generation." }, "moderation": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageModeration", "description": "Content moderation level. GPT image models only." } ] }, "n": { "type": [ "integer", "null" ], "format": "int32", "description": "Number of images to generate (1-10). For dall-e-3, only n=1 is supported." }, "output_compression": { "type": [ "integer", "null" ], "format": "int32", "description": "Compression level (0-100%) for webp/jpeg output. GPT image models only." }, "output_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageOutputFormat", "description": "Output format for GPT image models (png, jpeg, webp)." } ] }, "partial_images": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PartialImages", "description": "Partial images configuration for streaming." } ] }, "prompt": { "type": "string", "description": "A text description of the desired image(s).\nMax 32000 chars for GPT image models, 1000 for dall-e-2, 4000 for dall-e-3." }, "quality": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageQuality", "description": "The quality of the generated image." } ] }, "response_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageResponseFormat", "description": "Format for returning generated images (url or b64_json)." } ] }, "size": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageSize", "description": "Size of the generated images." } ] }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "**Hadrian Extension:** Per-request sovereignty requirements.\nMerged with API key requirements (most restrictive wins)." } ] }, "stream": { "type": [ "boolean", "null" ], "description": "Generate image in streaming mode. GPT image models only." }, "style": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageStyle", "description": "Image style. dall-e-3 only." } ] }, "user": { "type": [ "string", "null" ], "description": "Unique identifier for the end-user for abuse detection." } } }, "CreateImageVariationRequest": { "type": "object", "description": "Create image variation request (POST /v1/images/variations)\n\nNote: This endpoint accepts multipart/form-data. The `image` field\nis a file upload, not a JSON field.", "properties": { "model": { "type": [ "string", "null" ], "description": "The model to use. Only dall-e-2 is supported for variations." }, "n": { "type": [ "integer", "null" ], "format": "int32", "description": "Number of images to generate (1-10)." }, "response_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageResponseFormat", "description": "Format for returning generated images (url or b64_json)." } ] }, "size": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageSize", "description": "Size of the generated images." } ] }, "user": { "type": [ "string", "null" ], "description": "Unique identifier for the end-user for abuse detection." } } }, "CreateModelPricing": { "type": "object", "description": "Request to create model pricing", "required": [ "owner", "provider", "model" ], "properties": { "cache_write_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M cache write tokens in microcents" }, "cached_input_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M cached input tokens in microcents" }, "input_per_1m_tokens": { "type": "integer", "format": "int64", "description": "Cost per 1M input tokens in microcents" }, "model": { "type": "string" }, "output_per_1m_tokens": { "type": "integer", "format": "int64", "description": "Cost per 1M output tokens in microcents" }, "owner": { "$ref": "#/components/schemas/PricingOwner" }, "per_1m_characters": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M characters in microcents (for TTS)" }, "per_image": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per image in microcents" }, "per_request": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per request in microcents" }, "per_second": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per second of audio in microcents (for transcription/translation)" }, "provider": { "type": "string" }, "reasoning_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M reasoning tokens in microcents" }, "source": { "$ref": "#/components/schemas/PricingSource" } } }, "CreateOrgRbacPolicy": { "type": "object", "description": "Request to create a new organization RBAC policy.", "required": [ "name", "condition" ], "properties": { "action": { "type": "string", "description": "Action pattern to match (e.g., \"read\", \"write\", \"delete\", \"*\")" }, "condition": { "type": "string", "description": "CEL expression that must evaluate to true for the policy to apply" }, "description": { "type": [ "string", "null" ], "description": "Optional description of what this policy does" }, "effect": { "$ref": "#/components/schemas/RbacPolicyEffect", "description": "Policy effect when condition matches (defaults to 'deny')" }, "enabled": { "type": "boolean", "description": "Whether this policy is active (defaults to true)" }, "name": { "type": "string", "description": "Human-readable name for this policy (unique per org)" }, "priority": { "type": "integer", "format": "int32", "description": "Priority for evaluation order (higher = evaluated first, defaults to 0)\nValid range: -1000 to 1000" }, "reason": { "type": [ "string", "null" ], "description": "Reason for creating this policy (stored in version history)" }, "resource": { "type": "string", "description": "Resource pattern to match (e.g., \"projects/*\", \"teams/engineering/*\", \"*\")" } } }, "CreateOrgScimConfig": { "type": "object", "description": "Request to create a new organization SCIM configuration.", "properties": { "create_users": { "type": "boolean", "description": "Whether to create new users when they don't exist (default: true)" }, "deactivate_deletes_user": { "type": "boolean", "description": "Whether deactivating a user deletes them entirely (default: false)" }, "default_org_role": { "type": "string", "description": "Default role for new users in the organization (default: \"member\")" }, "default_team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Default team to add new users to (optional)" }, "default_team_role": { "type": "string", "description": "Default role for new users in the default team (default: \"member\")" }, "enabled": { "type": "boolean", "description": "Whether SCIM provisioning is enabled (default: true)" }, "revoke_api_keys_on_deactivate": { "type": "boolean", "description": "Whether to revoke all API keys when user is deactivated (default: true)" }, "sync_display_name": { "type": "boolean", "description": "Whether to sync display name from SCIM on updates (default: true)" } } }, "CreateOrgSsoConfig": { "type": "object", "description": "Request to create a new organization SSO configuration.", "properties": { "allowed_email_domains": { "type": "array", "items": { "type": "string" }, "description": "Allowed email domains (empty = allow all)" }, "client_id": { "type": [ "string", "null" ], "description": "OAuth2 client ID (required for OIDC, not used for SAML)" }, "client_secret": { "type": [ "string", "null" ], "description": "OAuth2 client secret (will be stored in secret manager)\nRequired for OIDC, not used for SAML" }, "create_users": { "type": "boolean", "description": "Whether to create new users on first login (default: true)" }, "default_org_role": { "type": "string", "description": "Default role for new users in the organization (default: \"member\")" }, "default_team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Default team to add new users to (optional)" }, "default_team_role": { "type": "string", "description": "Default role for new users in the default team (default: \"member\")" }, "discovery_url": { "type": [ "string", "null" ], "description": "Discovery URL for OIDC metadata (optional - defaults to issuer/.well-known/openid-configuration)" }, "enabled": { "type": "boolean", "description": "Whether this SSO config is active (default: true)" }, "enforcement_mode": { "$ref": "#/components/schemas/SsoEnforcementMode", "description": "SSO enforcement mode (default: optional)" }, "groups_claim": { "type": [ "string", "null" ], "description": "JWT claim containing group memberships (optional)" }, "identity_claim": { "type": "string", "description": "JWT claim to use as the user's identity (default: \"sub\")" }, "issuer": { "type": [ "string", "null" ], "description": "OIDC issuer URL (e.g., \"https://accounts.google.com\")\nRequired for OIDC, not used for SAML" }, "org_claim": { "type": [ "string", "null" ], "description": "JWT claim containing organization IDs (optional)" }, "provider_type": { "$ref": "#/components/schemas/SsoProviderType", "description": "Provider type (defaults to 'oidc')" }, "provisioning_enabled": { "type": "boolean", "description": "Whether JIT provisioning is enabled (default: true)" }, "redirect_uri": { "type": [ "string", "null" ], "description": "Redirect URI for OAuth2 callback (optional - uses global default if not set)" }, "saml_authn_context_class_ref": { "type": [ "string", "null" ], "description": "Requested authentication context class" }, "saml_email_attribute": { "type": [ "string", "null" ], "description": "SAML attribute name for email" }, "saml_force_authn": { "type": "boolean", "description": "Whether to force re-authentication at IdP (default: false)" }, "saml_groups_attribute": { "type": [ "string", "null" ], "description": "SAML attribute name for groups" }, "saml_identity_attribute": { "type": [ "string", "null" ], "description": "SAML attribute name for user identity (like identity_claim for OIDC)" }, "saml_idp_certificate": { "type": [ "string", "null" ], "description": "IdP X.509 certificate for signature validation (PEM format)" }, "saml_idp_entity_id": { "type": [ "string", "null" ], "description": "IdP entity identifier (e.g., \"https://idp.example.com/metadata\")" }, "saml_idp_slo_url": { "type": [ "string", "null" ], "description": "IdP Single Logout service URL (optional)" }, "saml_idp_sso_url": { "type": [ "string", "null" ], "description": "IdP Single Sign-On service URL (HTTP-Redirect or HTTP-POST binding)" }, "saml_metadata_url": { "type": [ "string", "null" ], "description": "IdP metadata URL for auto-configuration (alternative to manual config)" }, "saml_name_attribute": { "type": [ "string", "null" ], "description": "SAML attribute name for display name" }, "saml_name_id_format": { "type": [ "string", "null" ], "description": "NameID format to request (e.g., 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress')" }, "saml_sign_requests": { "type": "boolean", "description": "Whether to sign AuthnRequests (default: false)" }, "saml_sp_certificate": { "type": [ "string", "null" ], "description": "SP X.509 certificate for metadata (PEM format)" }, "saml_sp_entity_id": { "type": [ "string", "null" ], "description": "Service Provider entity ID (Hadrian's identifier to the IdP)" }, "saml_sp_private_key": { "type": [ "string", "null" ], "description": "SP private key for signing AuthnRequests (PEM format, will be stored in secret manager)" }, "scopes": { "type": "array", "items": { "type": "string" }, "description": "OAuth2 scopes to request (defaults to [\"openid\", \"email\", \"profile\"])" }, "sync_attributes_on_login": { "type": "boolean", "description": "Whether to sync user attributes on each login (default: false)" }, "sync_memberships_on_login": { "type": "boolean", "description": "Whether to sync team memberships from IdP groups on each login (default: true)" } } }, "CreateOrganization": { "type": "object", "required": [ "slug", "name" ], "properties": { "name": { "type": "string", "description": "Display name" }, "slug": { "type": "string", "description": "URL-friendly identifier (lowercase alphanumeric with hyphens)" } } }, "CreateProject": { "type": "object", "required": [ "slug", "name" ], "properties": { "name": { "type": "string", "description": "Display name" }, "slug": { "type": "string", "description": "URL-friendly identifier (lowercase alphanumeric with hyphens)" }, "team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Team to assign the project to (optional)" } } }, "CreateResponsesPayload": { "type": "object", "description": "Create responses request (OpenAI Responses API)", "properties": { "background": { "type": [ "boolean", "null" ], "description": "Run in background" }, "context_management": { "type": "array", "items": { "type": "object" }, "description": "Context management directives. Forwarded verbatim to providers\nthat support server-side compaction (OpenAI, Azure OpenAI); for\nothers the field is ignored at the adapter layer. See OpenAI's\ncompaction guide for the schema; the canonical entry is\n`{\"type\": \"compaction\", \"compact_threshold\": }`." }, "frequency_penalty": { "type": [ "number", "null" ], "format": "double", "description": "**Hadrian Extension:** Frequency penalty (-2.0 to 2.0)" }, "include": { "type": "array", "items": { "type": "string" }, "description": "Items to include in response" }, "input": { "type": "object", "description": "Input messages/items" }, "instructions": { "type": [ "string", "null" ], "description": "System instructions" }, "max_output_tokens": { "type": [ "number", "null" ], "format": "double", "description": "Maximum output tokens" }, "metadata": { "type": "object", "description": "Request metadata" }, "model": { "type": [ "string", "null" ], "description": "Model to use" }, "models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "**Hadrian Extension:** List of models for multi-model routing (alternative to single model)" }, "parallel_tool_calls": { "type": [ "boolean", "null" ], "description": "Allow parallel tool calls" }, "plugins": { "type": "array", "items": { "type": "object" }, "description": "**Hadrian Extension:** Plugins to enable for this request" }, "presence_penalty": { "type": [ "number", "null" ], "format": "double", "description": "**Hadrian Extension:** Presence penalty (-2.0 to 2.0)" }, "previous_response_id": { "type": [ "string", "null" ], "description": "Previous response ID for conversation continuation" }, "prompt": { "type": "object", "description": "Prompt template reference" }, "prompt_cache_key": { "type": [ "string", "null" ], "description": "Prompt cache key" }, "provider": { "type": "object", "description": "**Hadrian Extension:** Provider routing configuration" }, "reasoning": { "type": "object", "description": "Reasoning configuration" }, "safety_identifier": { "type": [ "string", "null" ], "description": "Safety identifier" }, "service_tier": { "type": "object", "description": "Service tier" }, "skills": { "type": "array", "items": { "type": "object" }, "description": "**Hadrian Extension:** Skills to mount into the shell-tool\nsession. Hadrian treats skills as a top-level request field\nrather than threading them through the OpenAI shell-tool\n`environment` block, so they're accepted on every responses\nrequest regardless of whether the upstream provider has its own\nskills surface.\n\nMirrors OpenAI's typed shape — each entry is either a reference\nto a stored skill or an inline bundle:\n\n```json\n[\n {\"type\": \"skill_reference\", \"skill_id\": \"\", \"version\": \"latest\"},\n {\"type\": \"inline\", \"name\": \"extract-csv\", \"description\": \"...\",\n \"source\": {\"type\": \"base64\", \"media_type\": \"text/markdown\", \"data\": \"...\"}}\n]\n```\n\nFor `skill_reference`, `skill_id` is a Hadrian skill UUID\nowned by the caller's org. `version` is optional; only\n`\"latest\"` (the default) is supported today — pinned versions\nreject with 400 until version-pinning lands.\n\nFor `inline`, the decoded `source.data` is mounted as an\nephemeral skill bundle: `text/markdown` is treated as the\n`SKILL.md` content; other media types are rejected today.\n\nEach resolved skill's `SKILL.md` is prepended to `instructions`\nso the model knows the skill is available; all skill files are\nmaterialized under `/skills//` inside the sandbox." }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "**Hadrian Extension:** Per-request sovereignty requirements.\nMerged with API key requirements (most restrictive wins)." } ] }, "store": { "type": [ "boolean", "null" ], "description": "Store response" }, "stream": { "type": "boolean", "description": "Enable streaming" }, "temperature": { "type": [ "number", "null" ], "format": "double", "description": "Sampling temperature (0.0 to 2.0)" }, "text": { "type": "object", "description": "Text configuration" }, "tool_choice": { "type": "object", "description": "Tool choice configuration" }, "tools": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/ResponsesToolDefinition" }, "description": "Available tools" }, "top_k": { "type": [ "number", "null" ], "format": "double", "description": "**Hadrian Extension:** Top-k sampling (supported by some providers like Anthropic)" }, "top_p": { "type": [ "number", "null" ], "format": "double", "description": "Nucleus sampling probability (0.0 to 1.0)" }, "truncation": { "type": "object", "description": "Truncation strategy" }, "user": { "type": [ "string", "null" ], "description": "User identifier for abuse detection" } } }, "CreateSelfServiceApiKey": { "type": "object", "description": "Self-service API key creation request (owner auto-set to current user).", "required": [ "name" ], "properties": { "allowed_models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Allowed models (null = all models)" }, "budget_limit_cents": { "type": [ "integer", "null" ], "format": "int64", "description": "Budget limit in cents" }, "budget_period": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/BudgetPeriod" } ] }, "expires_at": { "type": [ "string", "null" ], "format": "date-time" }, "ip_allowlist": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "IP allowlist in CIDR notation (null = all IPs)" }, "name": { "type": "string" }, "rate_limit_rpm": { "type": [ "integer", "null" ], "format": "int32", "description": "Requests per minute override" }, "rate_limit_tpm": { "type": [ "integer", "null" ], "format": "int32", "description": "Tokens per minute override" }, "scopes": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Permission scopes (null = full access)" }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "Sovereignty requirements for model access" } ] } } }, "CreateSelfServiceProvider": { "type": "object", "description": "Self-service create DTO (owner is inferred from the authenticated user)", "required": [ "name", "provider_type" ], "properties": { "api_key": { "type": [ "string", "null" ], "description": "Raw API key (stored in secrets manager if available, otherwise stored directly)" }, "base_url": { "type": "string", "description": "Base URL for the provider (required for OpenAI/Anthropic/Azure, optional for Bedrock/Vertex)" }, "config": { "description": "Provider-specific configuration (e.g., region, credentials for Bedrock/Vertex)" }, "models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "List of supported model names" }, "name": { "type": "string" }, "provider_type": { "type": "string", "description": "Provider type (e.g., \"openai\", \"anthropic\", \"bedrock\", \"vertex\")" }, "sovereignty": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyMetadata", "description": "Sovereignty and compliance metadata" } ] } } }, "CreateServiceAccount": { "type": "object", "description": "Request to create a new service account", "required": [ "slug", "name" ], "properties": { "description": { "type": [ "string", "null" ], "description": "Optional description" }, "name": { "type": "string", "description": "Display name" }, "roles": { "type": "array", "items": { "type": "string" }, "description": "Roles to assign (freeform strings, defaults to empty)" }, "slug": { "type": "string", "description": "URL-friendly identifier (lowercase alphanumeric with hyphens)" } } }, "CreateSkill": { "type": "object", "description": "Request to create a new skill. `files` must contain exactly one entry\nwith `path == \"SKILL.md\"`; the service layer rejects otherwise.", "required": [ "owner", "name", "description", "files" ], "properties": { "allowed_tools": { "type": [ "array", "null" ], "items": { "type": "string" } }, "argument_hint": { "type": [ "string", "null" ] }, "description": { "type": "string" }, "disable_model_invocation": { "type": [ "boolean", "null" ] }, "files": { "type": "array", "items": { "$ref": "#/components/schemas/SkillFileInput" } }, "frontmatter_extra": { "type": [ "object", "null" ], "additionalProperties": {}, "propertyNames": { "type": "string" } }, "name": { "type": "string" }, "owner": { "$ref": "#/components/schemas/SkillOwner" }, "source_ref": { "type": [ "string", "null" ] }, "source_url": { "type": [ "string", "null" ] }, "user_invocable": { "type": [ "boolean", "null" ] } } }, "CreateSpeechRequest": { "type": "object", "description": "Create speech request (POST /v1/audio/speech)", "required": [ "model", "input", "voice" ], "properties": { "input": { "type": "string", "description": "The text to generate audio for. Maximum length is 4096 characters." }, "instructions": { "type": [ "string", "null" ], "description": "Control the voice with additional instructions. Does not work with tts-1 or tts-1-hd." }, "model": { "type": "string", "description": "One of the available TTS models: tts-1, tts-1-hd, or gpt-4o-mini-tts." }, "response_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SpeechResponseFormat", "description": "The format of the audio output." } ] }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "**Hadrian Extension:** Per-request sovereignty requirements.\nMerged with API key requirements (most restrictive wins)." } ] }, "speed": { "type": [ "number", "null" ], "format": "float", "description": "The speed of the generated audio. Select a value from 0.25 to 4.0. Default is 1.0." }, "stream_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SpeechStreamFormat", "description": "The format to stream the audio in. Supported formats are sse and audio." } ] }, "voice": { "$ref": "#/components/schemas/Voice", "description": "The voice to use when generating the audio." } } }, "CreateSsoGroupMapping": { "type": "object", "description": "Request to create a new SSO group mapping.", "required": [ "idp_group" ], "properties": { "idp_group": { "type": "string", "description": "The IdP group name exactly as it appears in the groups claim" }, "priority": { "type": "integer", "format": "int32", "description": "Priority for role precedence (higher = wins when multiple mappings target same team)\nDefaults to 0 if not specified." }, "role": { "type": [ "string", "null" ], "description": "Role to assign (within the team if team_id is set, otherwise org-level role)" }, "sso_connection_name": { "type": "string", "description": "Which SSO connection this mapping applies to (defaults to 'default')" }, "team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Team to add users to when they have this IdP group (optional)" } } }, "CreateTeam": { "type": "object", "required": [ "slug", "name" ], "properties": { "name": { "type": "string", "description": "Display name" }, "slug": { "type": "string", "description": "URL-friendly identifier (lowercase alphanumeric with hyphens)" } } }, "CreateTemplate": { "type": "object", "description": "Request to create a new template", "required": [ "owner", "name", "content" ], "properties": { "content": { "type": "string", "description": "The actual template content" }, "description": { "type": [ "string", "null" ], "description": "Optional description" }, "metadata": { "type": [ "object", "null" ], "description": "Optional metadata", "additionalProperties": {}, "propertyNames": { "type": "string" } }, "name": { "type": "string", "description": "Name of the template (unique per owner)" }, "owner": { "$ref": "#/components/schemas/TemplateOwner", "description": "Owner of the template" } } }, "CreateTranscriptionRequest": { "type": "object", "description": "Create transcription request (POST /v1/audio/transcriptions)\n\nNote: This endpoint accepts multipart/form-data. The `file` field\nis a file upload, not a JSON field.", "required": [ "model" ], "properties": { "chunking_strategy": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/TranscriptionChunkingStrategy", "description": "Chunking strategy for the transcription." } ] }, "include": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/TranscriptionInclude" }, "description": "Additional information to include in the response." }, "known_speaker_names": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Speaker names corresponding to known_speaker_references. Up to 4 speakers." }, "known_speaker_references": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Audio samples as data URLs for known speaker references. 2-10 seconds each." }, "language": { "type": [ "string", "null" ], "description": "The language of the input audio in ISO-639-1 format (e.g., \"en\").\nSupplying the input language improves accuracy and latency." }, "model": { "type": "string", "description": "ID of the model to use. Options: gpt-4o-transcribe, gpt-4o-mini-transcribe,\nwhisper-1, gpt-4o-transcribe-diarize." }, "prompt": { "type": [ "string", "null" ], "description": "Optional text to guide the model's style or continue a previous audio segment.\nThe prompt should match the audio language." }, "response_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AudioResponseFormat", "description": "The format of the output." } ] }, "stream": { "type": [ "boolean", "null" ], "description": "If true, stream the response using server-sent events.\nNot supported for whisper-1." }, "temperature": { "type": [ "number", "null" ], "format": "float", "description": "The sampling temperature, between 0 and 1." }, "timestamp_granularities": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/TimestampGranularity" }, "description": "The timestamp granularities to populate. Requires response_format=verbose_json." } } }, "CreateTranslationRequest": { "type": "object", "description": "Create translation request (POST /v1/audio/translations)\n\nNote: This endpoint accepts multipart/form-data. The `file` field\nis a file upload, not a JSON field.", "required": [ "model" ], "properties": { "model": { "type": "string", "description": "ID of the model to use. Only whisper-1 is currently available." }, "prompt": { "type": [ "string", "null" ], "description": "Optional text to guide the model's style or continue a previous audio segment.\nThe prompt should be in English." }, "response_format": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AudioResponseFormat", "description": "The format of the output." } ] }, "temperature": { "type": [ "number", "null" ], "format": "float", "description": "The sampling temperature, between 0 and 1." } } }, "CreateUser": { "type": "object", "required": [ "external_id" ], "properties": { "email": { "type": [ "string", "null" ] }, "external_id": { "type": "string", "description": "External identifier (e.g., from SSO provider)" }, "name": { "type": [ "string", "null" ] } } }, "CreateVectorStore": { "type": "object", "description": "Request to create a new vector store.\n\n## Hadrian Extensions\n\nThe following fields are **Hadrian extensions** not present in the standard OpenAI API:\n- `owner`: Multi-tenancy support (required, specifies organization/project/user ownership)\n- `embedding_model`: Custom embedding model selection (default: text-embedding-3-small)\n- `embedding_dimensions`: Custom embedding dimensions (default: 1536)\n\n## OpenAI Compatibility Notes\n\n- `name` is optional (OpenAI-compatible), but a name will be auto-generated if not provided", "required": [ "owner" ], "properties": { "chunking_strategy": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ChunkingStrategy", "description": "The chunking strategy used to chunk the file(s). If not set, will use the `auto` strategy.\nOnly applicable if `file_ids` is non-empty." } ] }, "description": { "type": [ "string", "null" ], "description": "Description of the vector store" }, "embedding_dimensions": { "type": "integer", "format": "int32", "description": "**Hadrian Extension:** Embedding dimensions (immutable after creation, default: 1536)" }, "embedding_model": { "type": "string", "description": "**Hadrian Extension:** Embedding model to use (immutable after creation, default: text-embedding-3-small)" }, "expires_after": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ExpiresAfter", "description": "Expiration policy" } ] }, "file_ids": { "type": "array", "items": { "type": "string", "format": "uuid" }, "description": "A list of File IDs that the vector store should use (max 500).\nFiles will be attached to the vector store after creation." }, "metadata": { "type": [ "object", "null" ], "description": "Custom metadata (up to 16 key-value pairs, keys max 64 chars, string values max 512 chars)", "additionalProperties": {}, "propertyNames": { "type": "string" } }, "name": { "type": [ "string", "null" ], "description": "Name of the vector store (optional, auto-generated if not provided)" }, "owner": { "$ref": "#/components/schemas/VectorStoreOwner", "description": "**Hadrian Extension:** Owner of the vector store (required for multi-tenancy)" } } }, "CreateVectorStoreFileRequest": { "type": "object", "description": "Request to add a file to a vector store", "required": [ "file_id" ], "properties": { "chunking_strategy": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ChunkingStrategy", "description": "Chunking strategy for processing the file" } ] }, "file_id": { "type": "string", "description": "The ID of the file to add (from the Files API)", "example": "file-550e8400-e29b-41d4-a716-446655440000" } } }, "CreatedApiKey": { "allOf": [ { "$ref": "#/components/schemas/ApiKey" }, { "type": "object", "required": [ "key" ], "properties": { "key": { "type": "string", "description": "The raw API key (only shown once at creation)" } } } ], "description": "Returned on creation only (contains the raw key)" }, "CreatedOrgScimConfig": { "type": "object", "description": "Result of creating a new SCIM config (includes the raw token, shown only once)", "required": [ "config", "token" ], "properties": { "config": { "$ref": "#/components/schemas/OrgScimConfig", "description": "The created SCIM configuration" }, "token": { "type": "string", "description": "The raw SCIM bearer token (only shown once at creation time!)\nFormat: \"scim_\" (e.g., \"scim_Abc123XyzDef456...\")" } } }, "DailyModelSpendResponse": { "type": "object", "description": "Daily usage breakdown by model", "required": [ "date", "model", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Audio duration in seconds" }, "character_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Character count (TTS input)" }, "date": { "type": "string", "description": "Date (YYYY-MM-DD)" }, "image_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Number of images generated" }, "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens used" }, "model": { "type": "string", "description": "Model name" }, "output_tokens": { "type": "integer", "format": "int64", "description": "Output tokens used" }, "request_count": { "type": "integer", "format": "int64", "description": "Number of requests" }, "total_cost": { "type": "number", "format": "double", "description": "Total cost in dollars for this day/model" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens used" } } }, "DailyOrgSpendResponse": { "type": "object", "description": "Daily usage breakdown by organization", "required": [ "date", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64" }, "character_count": { "type": "integer", "format": "int64" }, "date": { "type": "string" }, "image_count": { "type": "integer", "format": "int64" }, "input_tokens": { "type": "integer", "format": "int64" }, "org_id": { "type": [ "string", "null" ] }, "org_name": { "type": [ "string", "null" ] }, "output_tokens": { "type": "integer", "format": "int64" }, "request_count": { "type": "integer", "format": "int64" }, "total_cost": { "type": "number", "format": "double" }, "total_tokens": { "type": "integer", "format": "int64" } } }, "DailyPricingSourceSpendResponse": { "type": "object", "description": "Daily usage breakdown by pricing source", "required": [ "date", "pricing_source", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Audio duration in seconds" }, "character_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Character count (TTS input)" }, "date": { "type": "string", "description": "Date (YYYY-MM-DD)" }, "image_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Number of images generated" }, "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens" }, "output_tokens": { "type": "integer", "format": "int64", "description": "Output tokens" }, "pricing_source": { "type": "string", "description": "Pricing source" }, "request_count": { "type": "integer", "format": "int64", "description": "Number of requests" }, "total_cost": { "type": "number", "format": "double", "description": "Total cost in dollars for this day/pricing source" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens" } } }, "DailyProjectSpendResponse": { "type": "object", "description": "Daily usage breakdown by project", "required": [ "date", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64" }, "character_count": { "type": "integer", "format": "int64" }, "date": { "type": "string" }, "image_count": { "type": "integer", "format": "int64" }, "input_tokens": { "type": "integer", "format": "int64" }, "output_tokens": { "type": "integer", "format": "int64" }, "project_id": { "type": [ "string", "null" ] }, "project_name": { "type": [ "string", "null" ] }, "request_count": { "type": "integer", "format": "int64" }, "total_cost": { "type": "number", "format": "double" }, "total_tokens": { "type": "integer", "format": "int64" } } }, "DailyProviderSpendResponse": { "type": "object", "description": "Daily usage breakdown by provider", "required": [ "date", "provider", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Audio duration in seconds" }, "character_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Character count (TTS input)" }, "date": { "type": "string", "description": "Date (YYYY-MM-DD)" }, "image_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Number of images generated" }, "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens used" }, "output_tokens": { "type": "integer", "format": "int64", "description": "Output tokens used" }, "provider": { "type": "string", "description": "Provider name" }, "request_count": { "type": "integer", "format": "int64", "description": "Number of requests" }, "total_cost": { "type": "number", "format": "double", "description": "Total cost in dollars for this day/provider" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens used" } } }, "DailySpendResponse": { "type": "object", "description": "Daily usage breakdown", "required": [ "date", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Audio duration in seconds" }, "character_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Character count (TTS input)" }, "date": { "type": "string", "description": "Date (YYYY-MM-DD)" }, "image_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Number of images generated" }, "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens used this day" }, "output_tokens": { "type": "integer", "format": "int64", "description": "Output tokens used this day" }, "request_count": { "type": "integer", "format": "int64", "description": "Number of requests this day" }, "total_cost": { "type": "number", "format": "double", "description": "Total cost in dollars for this day" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens used this day" } } }, "DailyTeamSpendResponse": { "type": "object", "description": "Daily usage breakdown by team", "required": [ "date", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64" }, "character_count": { "type": "integer", "format": "int64" }, "date": { "type": "string" }, "image_count": { "type": "integer", "format": "int64" }, "input_tokens": { "type": "integer", "format": "int64" }, "output_tokens": { "type": "integer", "format": "int64" }, "request_count": { "type": "integer", "format": "int64" }, "team_id": { "type": [ "string", "null" ] }, "team_name": { "type": [ "string", "null" ] }, "total_cost": { "type": "number", "format": "double" }, "total_tokens": { "type": "integer", "format": "int64" } } }, "DailyUserSpendResponse": { "type": "object", "description": "Daily usage breakdown by user", "required": [ "date", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64" }, "character_count": { "type": "integer", "format": "int64" }, "date": { "type": "string" }, "image_count": { "type": "integer", "format": "int64" }, "input_tokens": { "type": "integer", "format": "int64" }, "output_tokens": { "type": "integer", "format": "int64" }, "request_count": { "type": "integer", "format": "int64" }, "total_cost": { "type": "number", "format": "double" }, "total_tokens": { "type": "integer", "format": "int64" }, "user_email": { "type": [ "string", "null" ] }, "user_id": { "type": [ "string", "null" ] }, "user_name": { "type": [ "string", "null" ] } } }, "DbModelPricing": { "type": "object", "description": "Database model for model pricing configuration", "required": [ "id", "owner", "provider", "model", "input_per_1m_tokens", "output_per_1m_tokens", "source", "created_at", "updated_at" ], "properties": { "cache_write_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M cache write tokens in microcents" }, "cached_input_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M cached input tokens in microcents" }, "created_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "input_per_1m_tokens": { "type": "integer", "format": "int64", "description": "Cost per 1M input tokens in microcents" }, "model": { "type": "string" }, "output_per_1m_tokens": { "type": "integer", "format": "int64", "description": "Cost per 1M output tokens in microcents" }, "owner": { "$ref": "#/components/schemas/PricingOwner" }, "per_1m_characters": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M characters in microcents (for TTS)" }, "per_image": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per image in microcents" }, "per_request": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per request in microcents" }, "per_second": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per second of audio in microcents (for transcription/translation)" }, "provider": { "type": "string" }, "reasoning_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M reasoning tokens in microcents" }, "source": { "$ref": "#/components/schemas/PricingSource", "description": "Source of this pricing" }, "updated_at": { "type": "string", "format": "date-time" } } }, "DeleteFileResponse": { "type": "object", "description": "Delete file response", "required": [ "id", "object", "deleted" ], "properties": { "deleted": { "type": "boolean", "description": "Whether the file was deleted" }, "id": { "type": "string", "description": "File ID that was deleted" }, "object": { "type": "string", "description": "Object type (always \"file\")" } } }, "DeleteVectorStoreFileResponse": { "type": "object", "description": "Delete vector store file response", "required": [ "id", "object", "deleted" ], "properties": { "deleted": { "type": "boolean", "description": "Whether the file was deleted from the vector store" }, "id": { "type": "string", "description": "Vector store file ID that was deleted" }, "object": { "type": "string", "description": "Object type (always \"vector_store.file.deleted\")" } } }, "DeleteVectorStoreResponse": { "type": "object", "description": "Delete vector store response", "required": [ "id", "object", "deleted" ], "properties": { "deleted": { "type": "boolean", "description": "Whether the vector store was deleted" }, "id": { "type": "string", "description": "Vector store ID that was deleted" }, "object": { "type": "string", "description": "Object type (always \"vector_store.deleted\")" } } }, "DeviceInfo": { "type": "object", "description": "Device information for enhanced session tracking.", "properties": { "device_description": { "type": [ "string", "null" ], "description": "Human-readable device description (parsed from user agent, truncated to 512 chars)\ne.g., \"Chrome 120 on Windows\"" }, "device_id": { "type": [ "string", "null" ], "description": "Device fingerprint ID (SHA256 hash of user agent, first 16 chars)" }, "ip_address": { "type": [ "string", "null" ], "description": "Client IP address" }, "user_agent": { "type": [ "string", "null" ], "description": "Raw User-Agent header value (truncated to 512 chars)" } } }, "DiscoverResponse": { "type": "object", "description": "Response for the /auth/discover endpoint.", "required": [ "org_id", "org_slug", "org_name", "has_sso", "sso_required", "enforcement_mode", "provider_type", "domain_verified" ], "properties": { "domain_verification_status": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/DomainVerificationStatus", "description": "Current verification status of the domain (pending, verified, failed).\nNone if no verification record exists for this domain." } ] }, "domain_verified": { "type": "boolean", "description": "Whether the email domain has been verified via DNS TXT record.\nSSO is only available for verified domains." }, "enforcement_mode": { "$ref": "#/components/schemas/SsoEnforcementMode", "description": "The SSO enforcement mode for this organization.\n- \"optional\": SSO is available but not required\n- \"required\": SSO is required; non-SSO auth will be blocked\n- \"test\": SSO enforcement is being tested; non-SSO auth is logged but allowed" }, "has_sso": { "type": "boolean", "description": "Whether the organization has SSO configured and the domain is verified.\nSSO is only available when both conditions are met." }, "idp_name": { "type": [ "string", "null" ], "description": "Display name for the identity provider (derived from issuer URL or IdP entity ID)" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization ID" }, "org_name": { "type": "string", "description": "Organization display name" }, "org_slug": { "type": "string", "description": "Organization slug (URL-friendly identifier)" }, "provider_type": { "$ref": "#/components/schemas/SsoProviderType", "description": "The SSO provider type (oidc or saml).\nDetermines which auth flow the frontend should use." }, "sso_required": { "type": "boolean", "description": "Whether SSO is required for this organization (enforcement_mode = \"required\").\nOnly true if has_sso is also true." }, "verified_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the domain was successfully verified (if applicable)." } } }, "DlqEntryResponse": { "type": "object", "description": "DLQ entry response.", "required": [ "id", "entry_type", "payload", "error", "retry_count", "created_at", "metadata" ], "properties": { "created_at": { "type": "string", "description": "When the entry was created (RFC3339)." }, "entry_type": { "type": "string", "description": "Type of the failed operation." }, "error": { "type": "string", "description": "Error message from the failed operation." }, "id": { "type": "string", "format": "uuid", "description": "Unique entry ID." }, "last_retry_at": { "type": [ "string", "null" ], "description": "When the entry was last retried (RFC3339)." }, "metadata": { "type": "object", "description": "Additional metadata.", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "payload": { "description": "The serialized payload that failed." }, "retry_count": { "type": "integer", "format": "int32", "description": "Number of retry attempts." } } }, "DlqListQuery": { "type": "object", "description": "Query parameters for listing DLQ entries with cursor-based pagination.", "properties": { "cursor": { "type": [ "string", "null" ], "description": "Cursor for keyset pagination. Encoded as base64 string.", "example": "MTczMzU4MDgwMDAwMDphYmMxMjM0NS02Nzg5LTAxMjMtNDU2Ny0wMTIzNDU2Nzg5YWI" }, "direction": { "type": [ "string", "null" ], "description": "Pagination direction: \"forward\" (default) or \"backward\"." }, "entry_type": { "type": [ "string", "null" ], "description": "Filter by entry type (e.g., \"usage_log\")." }, "limit": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum number of entries to return (default: 100)." }, "max_retries": { "type": [ "integer", "null" ], "format": "int32", "description": "Only return entries with fewer than this many retries." } } }, "DlqListResponse": { "type": "object", "description": "Paginated list of DLQ entries.", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/DlqEntryResponse" }, "description": "List of DLQ entries." }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata." } } }, "DlqRetryResponse": { "type": "object", "description": "Result of a retry operation.", "required": [ "success", "message" ], "properties": { "message": { "type": "string", "description": "Message describing the result." }, "success": { "type": "boolean", "description": "Whether the retry was successful." } } }, "DlqStatsResponse": { "type": "object", "description": "DLQ statistics response.", "required": [ "total_entries", "is_empty", "by_type", "by_retry_count" ], "properties": { "by_retry_count": { "type": "object", "description": "Breakdown by retry count.", "additionalProperties": { "type": "integer", "format": "int64", "minimum": 0 }, "propertyNames": { "type": "integer", "format": "int32" } }, "by_type": { "type": "object", "description": "Breakdown by entry type.", "additionalProperties": { "type": "integer", "format": "int64", "minimum": 0 }, "propertyNames": { "type": "string" } }, "is_empty": { "type": "boolean", "description": "Whether the queue is empty." }, "total_entries": { "type": "integer", "format": "int64", "description": "Total number of entries in the queue.", "minimum": 0 } } }, "DomainVerification": { "type": "object", "description": "Domain verification record for SSO.\n\nTracks the verification status of email domains claimed by an organization's\nSSO configuration. Domains must be verified via DNS TXT record before SSO\ncan be enforced for users with that email domain.", "required": [ "id", "org_sso_config_id", "domain", "verification_token", "status", "verification_attempts", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time", "description": "When this record was created" }, "dns_txt_record": { "type": [ "string", "null" ], "description": "The actual DNS TXT record found during verification (for audit)" }, "domain": { "type": "string", "description": "The domain being verified (e.g., \"acme.com\")" }, "expires_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Optional: require re-verification after this date" }, "id": { "type": "string", "format": "uuid", "description": "Unique identifier for this verification record" }, "last_attempt_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last verification attempt timestamp" }, "org_sso_config_id": { "type": "string", "format": "uuid", "description": "SSO config this verification belongs to" }, "status": { "$ref": "#/components/schemas/DomainVerificationStatus", "description": "Current verification status" }, "updated_at": { "type": "string", "format": "date-time", "description": "When this record was last updated" }, "verification_attempts": { "type": "integer", "format": "int32", "description": "Number of verification attempts" }, "verification_token": { "type": "string", "description": "Random token for DNS TXT record verification" }, "verified_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the domain was successfully verified" } } }, "DomainVerificationInstructions": { "type": "object", "description": "Instructions for verifying a domain.", "required": [ "domain", "record_type", "record_host", "record_value", "instructions" ], "properties": { "domain": { "type": "string", "description": "The domain being verified" }, "instructions": { "type": "string", "description": "Human-readable instructions" }, "record_host": { "type": "string", "description": "DNS record host/name" }, "record_type": { "type": "string", "description": "DNS record type to create" }, "record_value": { "type": "string", "description": "DNS record value" } } }, "DomainVerificationStatus": { "type": "string", "description": "Domain verification status.", "enum": [ "pending", "verified", "failed" ] }, "DynamicProvider": { "type": "object", "required": [ "id", "name", "owner", "provider_type", "base_url", "models", "is_enabled", "created_at", "updated_at" ], "properties": { "api_key_secret_ref": { "type": [ "string", "null" ], "description": "Reference to API key in secrets manager (or literal key if no SM configured)" }, "base_url": { "type": "string" }, "config": { "description": "Provider-specific configuration (e.g., region, credentials for Bedrock/Vertex)" }, "created_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "is_enabled": { "type": "boolean" }, "models": { "type": "array", "items": { "type": "string" }, "description": "List of supported model names" }, "name": { "type": "string" }, "owner": { "$ref": "#/components/schemas/ProviderOwner" }, "provider_type": { "type": "string", "description": "Provider type (e.g., \"open_ai\", \"anthropic\", \"bedrock\", \"vertex\")" }, "sovereignty": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyMetadata", "description": "Sovereignty and compliance metadata" } ] }, "updated_at": { "type": "string", "format": "date-time" } } }, "DynamicProviderListResponse": { "type": "object", "description": "Paginated list of dynamic providers", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/DynamicProviderResponse" }, "description": "List of dynamic providers" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "DynamicProviderResponse": { "type": "object", "description": "Response DTO for dynamic providers", "required": [ "id", "name", "owner", "provider_type", "base_url", "has_api_key", "models", "is_enabled", "created_at", "updated_at" ], "properties": { "base_url": { "type": "string" }, "config": { "description": "Provider-specific configuration" }, "created_at": { "type": "string", "format": "date-time" }, "has_api_key": { "type": "boolean", "description": "Whether this provider has an API key configured" }, "id": { "type": "string", "format": "uuid" }, "is_enabled": { "type": "boolean" }, "models": { "type": "array", "items": { "type": "string" } }, "name": { "type": "string" }, "owner": { "$ref": "#/components/schemas/ProviderOwner" }, "provider_type": { "type": "string" }, "sovereignty": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyMetadata", "description": "Sovereignty and compliance metadata" } ] }, "updated_at": { "type": "string", "format": "date-time" } } }, "EligibleOwner": { "type": "object", "description": "One owner the current user could pick on the OAuth consent page.", "required": [ "id", "slug", "name" ], "properties": { "id": { "type": "string", "format": "uuid", "description": "Owner ID (uuid)." }, "name": { "type": "string", "description": "Display name shown in the picker." }, "org_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Parent organization id, if applicable. `None` for orgs themselves\nand the user's own identity." }, "org_slug": { "type": [ "string", "null" ], "description": "Parent organization slug, if applicable." }, "role": { "type": [ "string", "null" ], "description": "User's role in the owner (member, admin, etc.). `None` for the user\nentry, where role is implicit." }, "slug": { "type": "string", "description": "Slug the user sees in URLs." } } }, "EligibleOwnersResponse": { "type": "object", "description": "Response from `GET /admin/v1/me/eligible-owners`.", "required": [ "user", "organizations", "teams", "projects" ], "properties": { "organizations": { "type": "array", "items": { "$ref": "#/components/schemas/EligibleOwner" }, "description": "Organizations the user belongs to." }, "projects": { "type": "array", "items": { "$ref": "#/components/schemas/EligibleOwner" }, "description": "Projects the user belongs to." }, "teams": { "type": "array", "items": { "$ref": "#/components/schemas/EligibleOwner" }, "description": "Teams the user belongs to." }, "user": { "$ref": "#/components/schemas/EligibleOwner", "description": "The current user as an owner choice — always present." } } }, "EmbeddingInput": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" } }, { "type": "array", "items": { "type": "number", "format": "double" } }, { "type": "array", "items": { "type": "array", "items": { "type": "number", "format": "double" } } }, { "type": "array", "items": { "type": "object" } } ], "description": "Embedding input (text, array of texts, tokens, or multimodal)" }, "EncodingFormat": { "type": "string", "description": "Encoding format for embeddings", "enum": [ "float", "base64" ] }, "ErrorInfo": { "type": "object", "description": "Error information matching OpenAI's error schema.\n\nOpenAI error format: `{\"error\": {\"type\": \"...\", \"message\": \"...\", \"param\": ..., \"code\": ...}}`", "required": [ "type", "message" ], "properties": { "code": { "type": [ "string", "null" ], "description": "Machine-readable error code (null if not applicable)", "example": "budget_exceeded" }, "message": { "type": "string", "description": "Human-readable error message", "example": "Budget limit exceeded for monthly period" }, "param": { "type": [ "string", "null" ], "description": "Parameter that caused the error (null if not applicable)", "example": null }, "request_id": { "type": [ "string", "null" ], "description": "**Hadrian Extension:** Request ID for correlating errors with logs.\nThis field is automatically populated by the gateway middleware.", "example": "550e8400-e29b-41d4-a716-446655440000" }, "type": { "type": "string", "description": "Error type classification (e.g., \"invalid_request_error\", \"authentication_error\")", "example": "invalid_request_error" } } }, "ErrorResponse": { "type": "object", "description": "Standard error response body", "required": [ "error" ], "properties": { "error": { "$ref": "#/components/schemas/ErrorInfo", "description": "Error information" } } }, "ExchangeCodeForKey": { "type": "object", "description": "Request body for the public `POST /oauth/token` endpoint.\n\nPer RFC 7636 §4.5, the server already knows `code_challenge_method` from\nthe authorization request, so the client does not need to re-submit it.\nWe keep it accepted-but-optional purely for sanity-checking — the\nstored method is what's actually used during verification.", "required": [ "code", "code_verifier" ], "properties": { "code": { "type": "string", "description": "The authorization code received via the callback URL. We generate\n256-bit codes, so anything shorter than ~32 chars is definitely not\none of ours; the upper bound just defends the deserializer." }, "code_challenge_method": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PkceCodeChallengeMethod", "description": "Optional client-side hint of the method used to derive the\nchallenge. If supplied and it doesn't match the method recorded at\nauthorize time, the request is rejected; if omitted, the stored\nmethod is used." } ] }, "code_verifier": { "type": "string", "description": "The original PKCE verifier the external app generated. Length range\nmatches RFC 7636 §4.1, which mandates 43–128 URL-safe characters." } } }, "ExpiresAfter": { "type": "object", "description": "Expiration policy for collections", "required": [ "anchor", "days" ], "properties": { "anchor": { "type": "string", "description": "Anchor timestamp for expiration (\"last_active_at\")" }, "days": { "type": "integer", "format": "int32", "description": "Number of days after anchor before expiration" } } }, "ExportFormat": { "type": "string", "description": "Export format for access review reports", "enum": [ "json", "csv" ] }, "ExportMappingEntry": { "type": "object", "description": "A single mapping entry in the export", "required": [ "idp_group", "priority", "sso_connection_name" ], "properties": { "idp_group": { "type": "string", "description": "The IdP group name" }, "priority": { "type": "integer", "format": "int32", "description": "Priority for role precedence (higher = wins when multiple mappings target same team)" }, "role": { "type": [ "string", "null" ], "description": "Role to assign" }, "sso_connection_name": { "type": "string", "description": "SSO connection name" }, "team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Team ID (if assigned to a team)" }, "team_name": { "type": [ "string", "null" ], "description": "Team name for reference (if assigned to a team)" } } }, "ExportResponse": { "type": "object", "description": "Response for JSON export of SSO group mappings", "required": [ "organization", "exported_at", "mappings" ], "properties": { "exported_at": { "type": "string", "format": "date-time", "description": "Export timestamp" }, "mappings": { "type": "array", "items": { "$ref": "#/components/schemas/ExportMappingEntry" }, "description": "List of mappings" }, "organization": { "type": "string", "description": "Organization slug" } } }, "ExportedApiKey": { "type": "object", "description": "API key export data (excludes sensitive hash)", "required": [ "id", "key_prefix", "name", "created_at" ], "properties": { "budget_limit_cents": { "type": [ "integer", "null" ], "format": "int64", "description": "Budget limit in cents (if set)" }, "budget_period": { "type": [ "string", "null" ], "description": "Budget period (daily/monthly)" }, "created_at": { "type": "string", "format": "date-time", "description": "When the key was created" }, "expires_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the key expires (if set)" }, "id": { "type": "string", "format": "uuid", "description": "API key ID" }, "key_prefix": { "type": "string", "description": "Key prefix for identification" }, "last_used_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last time the key was used" }, "name": { "type": "string", "description": "User-assigned name" }, "revoked_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the key was revoked (if revoked)" } } }, "ExportedSession": { "type": "object", "description": "Session export data for user data export", "required": [ "id", "created_at", "expires_at" ], "properties": { "created_at": { "type": "string", "format": "date-time", "description": "When the session was created" }, "device_description": { "type": [ "string", "null" ], "description": "Device description (e.g., \"Chrome 120 on Windows\")" }, "expires_at": { "type": "string", "format": "date-time", "description": "When the session expires" }, "id": { "type": "string", "format": "uuid", "description": "Session ID" }, "ip_address": { "type": [ "string", "null" ], "description": "Client IP address" }, "last_activity": { "type": [ "string", "null" ], "format": "date-time", "description": "Last activity timestamp" } } }, "ExportedUsageSummary": { "type": "object", "description": "Usage summary for export", "required": [ "total_cost_microcents", "total_tokens", "request_count" ], "properties": { "first_request_at": { "type": [ "string", "null" ], "format": "date-time", "description": "First request timestamp" }, "last_request_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last request timestamp" }, "request_count": { "type": "integer", "format": "int64", "description": "Total number of API requests" }, "total_cost_microcents": { "type": "integer", "format": "int64", "description": "Total cost in microcents" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens used" } } }, "File": { "type": "object", "description": "A file (OpenAI Files API compatible)\nFiles are uploaded via the Files API and can then be added to vector stores\n\n## OpenAI Compatibility Notes\n\n- `id` is serialized with `file-` prefix (e.g., `file-550e8400-e29b-41d4-a716-446655440000`)", "required": [ "id", "owner_type", "owner_id", "filename", "purpose", "bytes", "status", "created_at" ], "properties": { "bytes": { "type": "integer", "format": "int64" }, "content_type": { "type": [ "string", "null" ], "description": "**Hadrian Extension:** MIME content type of the file" }, "created_at": { "type": "string", "format": "date-time" }, "expires_at": { "type": [ "string", "null" ], "format": "date-time" }, "filename": { "type": "string" }, "id": { "type": "string", "description": "File ID (serialized with `file-` prefix for OpenAI compatibility)", "example": "file-550e8400-e29b-41d4-a716-446655440000" }, "object": { "type": "string", "description": "Object type identifier (always \"file\" for API compatibility)" }, "owner_id": { "type": "string", "format": "uuid", "description": "**Hadrian Extension:** Owner ID for multi-tenancy" }, "owner_type": { "$ref": "#/components/schemas/VectorStoreOwnerType", "description": "**Hadrian Extension:** Owner type for multi-tenancy (organization, project, or user)" }, "purpose": { "$ref": "#/components/schemas/FilePurpose" }, "status": { "$ref": "#/components/schemas/FileStatus" }, "status_details": { "type": [ "string", "null" ] } } }, "FileBatch": { "type": "object", "description": "File batch response", "required": [ "id", "object", "vector_store_id", "status", "file_counts", "created_at" ], "properties": { "created_at": { "type": "integer", "format": "int64", "description": "Unix timestamp when batch was created" }, "file_counts": { "$ref": "#/components/schemas/FileBatchCounts", "description": "File counts by status" }, "id": { "type": "string", "description": "Batch ID" }, "object": { "type": "string", "description": "Object type (always \"vector_store.file_batch\")" }, "status": { "type": "string", "description": "Batch status" }, "vector_store_id": { "type": "string", "description": "Vector store ID" } } }, "FileBatchCounts": { "type": "object", "description": "File batch counts", "required": [ "in_progress", "completed", "failed", "cancelled", "total" ], "properties": { "cancelled": { "type": "integer", "format": "int32" }, "completed": { "type": "integer", "format": "int32" }, "failed": { "type": "integer", "format": "int32" }, "in_progress": { "type": "integer", "format": "int32" }, "total": { "type": "integer", "format": "int32" } } }, "FileCounts": { "type": "object", "description": "File counts for a vector store (OpenAI-compatible).\n\nThese counts are **derived statistics** recalculated from the current state of\nvector store files. They are NOT incremented/decremented manually, which prevents\nrace conditions and ensures eventual consistency.\n\n## When Counts Update\n\n`file_counts` is automatically refreshed after these operations:\n\n1. **File added** (`add_file`): New file link created with `in_progress` status\n2. **Status changed** (`update_vector_store_file_status`): File transitions to\n `completed`, `failed`, or `cancelled`\n3. **Usage updated** (`update_vector_store_file_usage`): After processing completes\n4. **File removed** (`remove_file`): Soft-delete excludes file from counts\n\n## Count Definitions\n\n- `in_progress`: Files currently being processed (chunking, embedding)\n- `completed`: Files successfully processed and searchable\n- `failed`: Files that encountered processing errors\n- `cancelled`: Files whose processing was cancelled\n- `total`: Sum of all non-deleted files (in_progress + completed + failed + cancelled)\n\n## Implementation Note\n\nCounts are calculated via SQL aggregation over `vector_store_files` where\n`deleted_at IS NULL`. Soft-deleted files are excluded from all counts.", "required": [ "cancelled", "completed", "failed", "in_progress", "total" ], "properties": { "cancelled": { "type": "integer", "format": "int32", "description": "Number of files whose processing was cancelled" }, "completed": { "type": "integer", "format": "int32", "description": "Number of files successfully processed and searchable" }, "failed": { "type": "integer", "format": "int32", "description": "Number of files that encountered processing errors" }, "in_progress": { "type": "integer", "format": "int32", "description": "Number of files currently being processed" }, "total": { "type": "integer", "format": "int32", "description": "Total number of files (sum of all statuses)" } } }, "FileError": { "type": "object", "description": "File error information (OpenAI-compatible)\n\nReturned when a file fails to be processed for a vector store.", "required": [ "code", "message" ], "properties": { "code": { "$ref": "#/components/schemas/FileErrorCode", "description": "Error code indicating the type of failure" }, "message": { "type": "string", "description": "Human-readable description of the error" } } }, "FileErrorCode": { "type": "string", "description": "Error codes for file processing failures (OpenAI-compatible)\n\nThese codes indicate why a file failed to be added to a vector store.", "enum": [ "server_error", "unsupported_file", "invalid_file" ] }, "FileListResponse": { "type": "object", "description": "Paginated list of files response (OpenAI-compatible).", "required": [ "object", "data", "has_more" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/File" }, "description": "List of files" }, "first_id": { "type": [ "string", "null" ], "description": "ID of the first file in the list" }, "has_more": { "type": "boolean", "description": "Whether there are more results available" }, "last_id": { "type": [ "string", "null" ], "description": "ID of the last file in the list" }, "object": { "type": "string", "description": "Object type (always \"list\")" } } }, "FilePurpose": { "type": "string", "description": "File purpose (OpenAI Files API compatible)", "enum": [ "assistants", "batch", "fine_tune", "vision" ] }, "FileSearchRanker": { "type": "string", "description": "The ranker algorithm to use for file search.\n\nControls which ranking algorithm is used to score and order search results.\nIf not specified, defaults to `auto`.", "enum": [ "auto", "vector", "hybrid", "llm", "none" ] }, "FileSearchRankingOptions": { "type": "object", "description": "Ranking options for file search.\n\nControls how search results are scored, ranked, and filtered.\n\n# Example (Vector-only search)\n\n```json\n{\n \"ranker\": \"vector\",\n \"score_threshold\": 0.5\n}\n```\n\n# Example (Hybrid search)\n\n```json\n{\n \"ranker\": \"hybrid\",\n \"score_threshold\": 0.5,\n \"hybrid_search\": {\n \"embedding_weight\": 0.7,\n \"text_weight\": 0.3\n }\n}\n```\n\n# Example (LLM re-ranking)\n\n```json\n{\n \"ranker\": \"llm\",\n \"score_threshold\": 0.5\n}\n```\n\n# Fields\n\n- `ranker`: The ranking algorithm to use (optional, defaults to `auto`)\n- `score_threshold`: Minimum similarity score (required, 0.0-1.0)\n- `hybrid_search`: Options for hybrid vector+keyword search (optional)", "required": [ "score_threshold" ], "properties": { "hybrid_search": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/HybridSearchOptions", "description": "**Hadrian Extension:** Options for hybrid search combining vector and keyword search.\n\nWhen provided with a ranker that supports hybrid search (`auto` or\n`hybrid`), enables hybrid search using Reciprocal Rank Fusion (RRF)\nto combine vector and keyword results.\n\nIf not provided, uses vector-only search." } ] }, "ranker": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/FileSearchRanker", "description": "The ranker to use for scoring results.\n\nIf not specified, defaults to `auto` which automatically selects\nthe best ranker based on the query characteristics." } ] }, "score_threshold": { "type": "number", "format": "double", "description": "The minimum similarity score threshold for results.\n\nResults with scores below this threshold will be filtered out.\nMust be a floating point number between 0.0 and 1.0.\n\n- `0.0`: Return all results regardless of score\n- `1.0`: Only return exact matches\n- Recommended: `0.5` for balanced precision/recall" } } }, "FileSearchTool": { "type": "object", "description": "File search tool for RAG in the Responses API.\nEnables semantic search across vector stores.", "required": [ "type", "vector_store_ids" ], "properties": { "cache_control": { "type": [ "object", "null" ], "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" }, "filters": { "type": [ "object", "null" ], "description": "Metadata filters to apply to the search." }, "max_num_results": { "type": [ "integer", "null" ], "description": "Maximum number of results to return.", "minimum": 0 }, "ranking_options": { "type": [ "object", "null" ], "description": "Ranking options for controlling result relevance." }, "type": { "$ref": "#/components/schemas/FileSearchToolType" }, "vector_store_ids": { "type": "array", "items": { "type": "string" }, "description": "Vector store IDs to search across." } } }, "FileSearchToolType": { "type": "string", "enum": [ "file_search" ] }, "FileStatus": { "type": "string", "description": "File upload status (OpenAI Files API compatible)\n\nTracks the state of a file uploaded via the Files API.\nNote: This status is **deprecated** in OpenAI's API but still returned for compatibility.\n\n## State Transitions\n\n```text\n┌──────────┐ validation ┌───────────┐\n│ uploaded │ ──────────────────▶ │ processed │\n└──────────┘ success └───────────┘\n │\n │ validation failed\n ▼\n┌──────────┐\n│ error │\n└──────────┘\n```\n\n- `uploaded`: File received and stored, initial validation pending\n- `processed`: File validated and ready for use (e.g., adding to vector stores)\n- `error`: File validation failed (see `status_details` for reason)\n\n## Important\n\nThis is the **file upload** status, not the vector store processing status.\nWhen a file is added to a vector store, its processing status is tracked\nseparately via `VectorStoreFileStatus`.", "enum": [ "uploaded", "processed", "error" ] }, "FilterValue": { "oneOf": [ { "type": "string", "description": "String value" }, { "type": "number", "format": "double", "description": "Numeric value (integer or float)" }, { "type": "boolean", "description": "Boolean value" }, { "type": "array", "items": { "$ref": "#/components/schemas/FilterValueItem" }, "description": "Array of values (for future `in`/`nin` support)" } ], "description": "A value that can be compared in a filter.\n\nSupports string, number (as f64), boolean, and arrays for `in`/`nin` operations." }, "FilterValueItem": { "oneOf": [ { "type": "string", "description": "String item" }, { "type": "number", "format": "double", "description": "Numeric item" } ], "description": "Items within a filter value array.\n\nUsed for `in`/`nin` operators (future support)." }, "ForecastQuery": { "type": "object", "description": "Query parameters for forecast endpoint", "properties": { "forecast_days": { "type": [ "integer", "null" ], "description": "Number of days to forecast ahead (default: 7)", "minimum": 0 }, "lookback_days": { "type": [ "integer", "null" ], "format": "int32", "description": "Number of days of historical data to use (default: 30)" } } }, "FunctionTool": { "allOf": [ { "type": "object", "description": "Extra fields the gateway forwards verbatim (e.g. MCP `annotations`\non rewritten function tools). Not part of OpenAI's documented\nshape; preserved here so internal rewrite pipelines can attach\nprovider-specific metadata without losing it through round-trips." }, { "type": "object", "required": [ "name" ], "properties": { "defer_loading": { "type": [ "boolean", "null" ], "description": "Delay loading the function definition until the model discovers it\nvia tool search. On a caller-supplied function tool this is\nforwarded to the provider and treated as opaque. On the per-tool\nfunction tools the MCP rewrite synthesizes it is only set on the\nnative-passthrough path (`McpTool::defer_loading_passthrough` on an\nOpenAI/Azure upstream); the default `hadrian_hosted` path defers via\nHadrian-side tool search instead and does not set this flag." }, "description": { "type": [ "string", "null" ], "description": "Human-readable description surfaced to the model." }, "name": { "type": "string", "description": "Function name. Must be `[A-Za-z0-9_-]{1,64}`." }, "parameters": { "type": [ "object", "null" ], "description": "JSON Schema describing the function's parameters. Forwarded\nverbatim to the provider; the gateway treats it as opaque." }, "strict": { "type": [ "boolean", "null" ], "description": "When true, the model is constrained to emit arguments that\nstrictly conform to `parameters`." }, "type": { "$ref": "#/components/schemas/FunctionToolType" } } } ], "description": "Custom function tool. **Schema-only**: at the wire level the gateway\nkeeps `Function` as an opaque `serde_json::Value` so existing\nrewrite pipelines (web_search → function, shell → function, MCP →\nper-tool function) can construct/inspect it via JSON without\ntouching a typed struct. This struct exists purely to give the\nOpenAPI spec a typed shape for the function-tool variant." }, "FunctionToolType": { "type": "string", "enum": [ "function" ] }, "HealthStatus": { "type": "string", "description": "Status of a provider's health.", "enum": [ "healthy", "unhealthy", "unknown" ] }, "HybridSearchOptions": { "type": "object", "description": "Options for hybrid search combining vector and keyword search.\n\nHybrid search uses Reciprocal Rank Fusion (RRF) to combine results from\ndense vector (semantic) search and sparse keyword (BM25/full-text) search.\nThe weights control how much each search method contributes to the final ranking.\n\n# Example\n\n```json\n{\n \"embedding_weight\": 0.7,\n \"text_weight\": 0.3\n}\n```\n\n# Weight Interpretation\n\n- Equal weights (1.0, 1.0): Balanced fusion, good default\n- Higher embedding_weight: Favor semantic similarity\n- Higher text_weight: Favor exact keyword matches\n\nWeights are relative; they don't need to sum to 1.0.", "required": [ "embedding_weight", "text_weight" ], "properties": { "embedding_weight": { "type": "number", "format": "double", "description": "The weight of the embedding (vector) search in reciprocal rank fusion.\n\nHigher values give more influence to semantic similarity matches.\nDefault: 1.0" }, "text_weight": { "type": "number", "format": "double", "description": "The weight of the text (keyword) search in reciprocal rank fusion.\n\nHigher values give more influence to exact keyword matches.\nDefault: 1.0" } } }, "IdentityInfo": { "type": "object", "description": "Identity information from the authentication source (IdP or proxy).", "required": [ "external_id", "roles", "idp_groups" ], "properties": { "email": { "type": [ "string", "null" ], "description": "Email address (if provided by IdP)" }, "external_id": { "type": "string", "description": "External identity ID (from IdP)" }, "idp_groups": { "type": "array", "items": { "type": "string" }, "description": "Raw IdP groups before any mapping.\nThese are the exact values from the IdP (e.g., OIDC groups claim).\nUseful for debugging SSO group mappings." }, "name": { "type": [ "string", "null" ], "description": "Display name (if provided by IdP)" }, "roles": { "type": "array", "items": { "type": "string" }, "description": "Roles from IdP (e.g., super_admin, org_admin, team_admin, user)" } } }, "Image": { "type": "object", "description": "Individual image data in response", "properties": { "b64_json": { "type": [ "string", "null" ], "description": "Base64-encoded image data (when response_format is b64_json)" }, "revised_prompt": { "type": [ "string", "null" ], "description": "The revised prompt used for generation (dall-e-3 only)" }, "url": { "type": [ "string", "null" ], "description": "URL of the generated image (when response_format is url)" } } }, "ImageBackground": { "type": "string", "description": "Image background transparency (GPT image models only)", "enum": [ "transparent", "opaque", "auto" ] }, "ImageInputTokensDetails": { "type": "object", "description": "Token usage details for image input", "properties": { "image_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Number of image tokens in input" }, "text_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Number of text tokens in input" } } }, "ImageModel": { "type": "string", "description": "Image generation model", "enum": [ "dall-e-2", "dall-e-3", "gpt-image-1", "gpt-image-1-mini", "gpt-image-1.5" ] }, "ImageModeration": { "type": "string", "description": "Content moderation level (GPT image models only)", "enum": [ "low", "auto" ] }, "ImageOutputFormat": { "type": "string", "description": "Image output format (GPT image models only)", "enum": [ "png", "jpeg", "webp" ] }, "ImageQuality": { "type": "string", "description": "Image quality setting", "enum": [ "standard", "hd", "low", "medium", "high", "auto" ] }, "ImageResponseFormat": { "type": "string", "description": "Image response format", "enum": [ "url", "b64_json" ] }, "ImageSize": { "type": "string", "description": "Image size for generation", "enum": [ "auto", "256x256", "512x512", "1024x1024", "1536x1024", "1024x1536", "1792x1024", "1024x1792" ] }, "ImageStyle": { "type": "string", "description": "Image style (dall-e-3 only)", "enum": [ "vivid", "natural" ] }, "ImageUrl": { "type": "object", "description": "Image URL reference", "required": [ "url" ], "properties": { "detail": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageUrlDetail" } ] }, "url": { "type": "string" } } }, "ImageUrlDetail": { "type": "string", "description": "Image detail level", "enum": [ "auto", "low", "high" ] }, "ImageUsage": { "type": "object", "description": "Token usage for image generation (GPT image models only)", "required": [ "total_tokens", "input_tokens", "output_tokens" ], "properties": { "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens used" }, "input_tokens_details": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageInputTokensDetails", "description": "Breakdown of input token types" } ] }, "output_tokens": { "type": "integer", "format": "int64", "description": "Output tokens used" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens used" } } }, "ImagesResponse": { "type": "object", "description": "Response from image generation endpoints", "required": [ "created" ], "properties": { "background": { "type": [ "string", "null" ], "description": "Background used (transparent or opaque)" }, "created": { "type": "integer", "format": "int64", "description": "Unix timestamp (seconds) when images were created" }, "data": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/Image" }, "description": "List of generated images" }, "output_format": { "type": [ "string", "null" ], "description": "Output format used (png, webp, jpeg)" }, "quality": { "type": [ "string", "null" ], "description": "Quality of generated images" }, "size": { "type": [ "string", "null" ], "description": "Size of generated images" }, "usage": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ImageUsage", "description": "Token usage (GPT image models only)" } ] } } }, "ImportConflictStrategy": { "type": "string", "description": "Conflict resolution strategy for import", "enum": [ "skip", "overwrite", "error" ] }, "ImportError": { "type": "object", "description": "Details about an import error", "required": [ "index", "idp_group", "error" ], "properties": { "error": { "type": "string", "description": "Error message" }, "idp_group": { "type": "string", "description": "The IdP group that caused the error" }, "index": { "type": "integer", "description": "Index of the mapping in the input array (0-based)", "minimum": 0 } } }, "ImportMappingEntry": { "type": "object", "description": "A single mapping entry to import", "required": [ "idp_group" ], "properties": { "idp_group": { "type": "string", "description": "The IdP group name exactly as it appears in the groups claim" }, "priority": { "type": "integer", "format": "int32", "description": "Priority for role precedence (higher = wins when multiple mappings target same team)\nDefaults to 0 if not specified." }, "role": { "type": [ "string", "null" ], "description": "Role to assign" }, "sso_connection_name": { "type": "string", "description": "SSO connection name (defaults to 'default')" }, "team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Team ID to add users to (optional, can use team_name instead)" } } }, "ImportRequest": { "type": "object", "description": "Request to import SSO group mappings", "required": [ "mappings" ], "properties": { "mappings": { "type": "array", "items": { "$ref": "#/components/schemas/ImportMappingEntry" }, "description": "List of mappings to import" }, "on_conflict": { "$ref": "#/components/schemas/ImportConflictStrategy", "description": "How to handle conflicts with existing mappings" } } }, "ImportResponse": { "type": "object", "description": "Response from importing SSO group mappings", "required": [ "created", "updated", "skipped", "errors" ], "properties": { "created": { "type": "integer", "description": "Number of mappings created", "minimum": 0 }, "errors": { "type": "array", "items": { "$ref": "#/components/schemas/ImportError" }, "description": "List of errors encountered" }, "skipped": { "type": "integer", "description": "Number of mappings skipped (already existed)", "minimum": 0 }, "updated": { "type": "integer", "description": "Number of mappings updated (overwritten)", "minimum": 0 } } }, "InputAudio": { "type": "object", "description": "Audio input", "required": [ "data", "format" ], "properties": { "data": { "type": "string", "description": "Base64-encoded audio data" }, "format": { "$ref": "#/components/schemas/InputAudioFormat" } } }, "InputAudioFormat": { "type": "string", "description": "Audio input format", "enum": [ "wav", "mp3", "flac", "m4a", "ogg", "pcm16", "pcm24" ] }, "JsonSchemaConfig": { "type": "object", "description": "JSON schema configuration for structured output", "required": [ "name" ], "properties": { "description": { "type": [ "string", "null" ] }, "name": { "type": "string" }, "schema": { "type": "object" }, "strict": { "type": [ "boolean", "null" ] } } }, "ListAccessibleQuery": { "type": "object", "description": "Query parameters for listing accessible conversations", "properties": { "limit": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum number of conversations to return" } } }, "ListDomainVerificationsResponse": { "type": "object", "description": "Response for list endpoint with total count.", "required": [ "items", "total" ], "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/DomainVerification" } }, "total": { "type": "integer", "format": "int64" } } }, "ListFilesQuery": { "type": "object", "required": [ "owner_type", "owner_id" ], "properties": { "after": { "type": [ "string", "null" ], "description": "Cursor for forward pagination. Returns results after this file ID." }, "before": { "type": [ "string", "null" ], "description": "**Hadrian Extension:** Cursor for backward pagination. Returns results before this file ID." }, "limit": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum number of files to return (default: 20, max: 100)" }, "order": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SortOrder", "description": "Sort order by `created_at` timestamp (default: desc)" } ] }, "owner_id": { "type": "string", "format": "uuid", "description": "**Hadrian Extension:** Owner ID for multi-tenancy" }, "owner_type": { "type": "string", "description": "**Hadrian Extension:** Owner type for multi-tenancy (organization, project, or user)" }, "purpose": { "type": [ "string", "null" ], "description": "Filter by purpose" } } }, "ListQuery": { "type": "object", "description": "Query parameters for list operations with cursor-based pagination.", "properties": { "cursor": { "type": [ "string", "null" ], "description": "Cursor for keyset pagination. Encoded as base64 string.", "example": "MTczMzU4MDgwMDAwMDphYmMxMjM0NS02Nzg5LTAxMjMtNDU2Ny0wMTIzNDU2Nzg5YWI" }, "direction": { "type": [ "string", "null" ], "description": "Pagination direction: \"forward\" (default) or \"backward\"." }, "include_deleted": { "type": [ "boolean", "null" ], "description": "Include soft-deleted records in results" }, "limit": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum number of results to return" } } }, "ListVectorStoreFilesQuery": { "type": "object", "description": "Query parameters for listing vector store files (OpenAI-compatible).", "properties": { "after": { "type": [ "string", "null" ], "description": "Cursor for forward pagination. Returns results after this file ID." }, "before": { "type": [ "string", "null" ], "description": "Cursor for backward pagination. Returns results before this file ID." }, "filter": { "type": [ "string", "null" ], "description": "Filter by status (in_progress, completed, failed, cancelled)" }, "limit": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum number of files to return (default: 20, max: 100)" }, "order": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SortOrder", "description": "Sort order by `created_at` timestamp (default: desc)" } ] } } }, "ListVectorStoresQuery": { "type": "object", "description": "Query parameters for listing vector stores.\n\n## OpenAI Compatibility\n\nThis endpoint supports OpenAI-compatible cursor-based pagination:\n- `limit`: Maximum number of results (1-100, default 20)\n- `order`: Sort order by `created_at` timestamp (asc/desc, default desc)\n- `after`: Cursor for forward pagination (object ID, e.g., `vs_abc123`)\n- `before`: Cursor for backward pagination (object ID, e.g., `vs_abc123`)\n\n## Hadrian Extensions\n\n- `owner_type`, `owner_id`: Optional for multi-tenancy scoping. When omitted, returns all\n vector stores accessible to the authenticated user based on their memberships.", "properties": { "after": { "type": [ "string", "null" ], "description": "Cursor for forward pagination. Returns results after this object ID.\nUse the `last_id` from a previous response to get the next page." }, "before": { "type": [ "string", "null" ], "description": "Cursor for backward pagination. Returns results before this object ID.\nUse the `first_id` from a previous response to get the previous page." }, "limit": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum number of vector stores to return (default: 20, max: 100)" }, "order": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SortOrder", "description": "Sort order by `created_at` timestamp (default: desc)" } ] }, "owner_id": { "type": [ "string", "null" ], "format": "uuid", "description": "**Hadrian Extension:** Owner ID for multi-tenancy.\nWhen omitted along with `owner_type`, returns all accessible vector stores." }, "owner_type": { "type": [ "string", "null" ], "description": "**Hadrian Extension:** Owner type for multi-tenancy (organization, team, project, or user).\nWhen omitted along with `owner_id`, returns all accessible vector stores." } } }, "LogicalOperator": { "type": "string", "description": "Logical operators for compound filters.", "enum": [ "and", "or" ] }, "McpAllowedTools": { "oneOf": [ { "type": "array", "items": { "type": "string" } }, { "$ref": "#/components/schemas/McpToolFilter" } ], "description": "Tool whitelist for an `McpTool`. Untagged so OpenAI's accepted\nshorthand `[\"tool_a\", \"tool_b\"]` round-trips as the `List` variant\nand the `{tool_names: [...], read_only?: bool}` object form picks\nup extra knobs." }, "McpApprovalFilter": { "type": "object", "description": "Object form of `require_approval`. `always` lists tools that must\nbe gated; `never` lists tools that bypass the gate. Tools not named\nin either fall back to the default (gate). Mirrors OpenAI's\n`MCPToolApprovalFilter`.", "properties": { "always": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/McpToolFilter", "description": "Tools that require approval." } ] }, "never": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/McpToolFilter", "description": "Tools exempt from approval." } ] } }, "additionalProperties": false }, "McpApprovalMode": { "type": "string", "enum": [ "always", "never" ] }, "McpRequireApproval": { "oneOf": [ { "$ref": "#/components/schemas/McpApprovalMode" }, { "$ref": "#/components/schemas/McpApprovalFilter" } ], "description": "Approval gating shape for the MCP tool. Accepts the spec's string\nshorthand (`\"always\"` / `\"never\"`) or an object with `always` / `never`\nfilters that opt subsets in or out of the approval gate." }, "McpTool": { "type": "object", "description": "MCP tool — lets the model invoke tools exposed by a remote Model\nContext Protocol server (Atlassian, Notion, GitHub, HuggingFace, …).\n\nMirrors OpenAI's `mcp` tool. Two mutually-exclusive shapes: pointing\nat a remote server via `server_url`, or pointing at an OpenAI\nfirst-party connector via `connector_id`. The caller supplies any\n`authorization` bearer token directly on the tool entry; Hadrian\ndoes not persist or rewrite it.\n\nUnder `mode = passthrough_openai` the tool entry is forwarded\nverbatim to OpenAI / Azure OpenAI, and non-OpenAI providers reject\nwith `mcp_passthrough_unsupported_provider`. Under\n`mode = hadrian_hosted` the gateway runs the MCP client loop itself\nvia `rmcp` and rewrites the tool into per-tool function tools, so\nany provider can drive it.", "required": [ "type", "server_label" ], "properties": { "allowed_tools": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/McpAllowedTools", "description": "Restrict which tools from the server are exposed to the model.\nAccepts either a flat list of tool names or an object form for\nforward-compat with extra knobs." } ] }, "authorization": { "type": [ "string", "null" ], "description": "Bearer / OAuth access token. The caller obtains this\nout-of-band (OpenAI's API does not run the OAuth dance for the\nremote server, and neither does Hadrian). Sent verbatim to the\nMCP server's `Authorization` header. Hadrian does not persist\nthe value — clients must include it on every request." }, "call_timeout_secs": { "type": [ "integer", "null" ], "format": "int64", "description": "**Hadrian Extension:** upper bound, in seconds, on a single\n`tools/call` round-trip to this MCP server under `hadrian_hosted`.\nOverrides the `[features.mcp].call_timeout_secs` deployment default\n(300s). On expiry the in-flight `mcp_call` terminates with\n`status=\"incomplete\"` and a timeout `error`. Not part of OpenAI's\nspec; ignored under `passthrough_openai` (the upstream owns the\ncall loop there).", "minimum": 0 }, "connector_id": { "type": [ "string", "null" ], "description": "Identifier for an OpenAI-maintained connector\n(e.g. `connector_googlecalendar`). Mutually exclusive with\n`server_url`. Only usable under `mode = passthrough_openai`;\n`hadrian_hosted` cannot reach OpenAI's connector registry." }, "defer_loading": { "type": [ "boolean", "null" ], "description": "Delay loading the tool definitions until the model discovers them\nvia tool search, rather than dumping the whole catalog into the\nprompt. Forwarded verbatim under `passthrough_openai` (OpenAI runs\nits native tool search). Under `hadrian_hosted` deferral is\nrealized by **Hadrian-side tool search**: the gateway exposes a\nsingle `tool_search` function tool, keeps the catalog server-side,\nand lazily injects matched per-tool function definitions as the\nmodel discovers them — so deferral works behind every provider,\nnot just OpenAI. The upstream `tools/list` catalog fetch always\nruns eagerly at rewrite time (it's needed to know what's\nsearchable); only the per-tool definitions are deferred." }, "defer_loading_passthrough": { "type": [ "boolean", "null" ], "description": "**Hadrian Extension:** opt out of Hadrian-side tool search and let\nthe upstream handle `defer_loading` natively. Only honored when\n`defer_loading` is set, the gateway is in `hadrian_hosted` mode,\nand the resolved provider is OpenAI / Azure OpenAI (which\nimplement native tool search); rejected with HTTP 400 otherwise.\nDefault/`None` keeps the provider-agnostic Hadrian-side path." }, "headers": { "type": [ "object", "null" ], "description": "Additional HTTP headers sent with every JSON-RPC call to the\nMCP server. Useful for region or workspace selectors.", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "require_approval": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/McpRequireApproval", "description": "Approval gate. Spec default is `\"always\"` when omitted — under\n`hadrian_hosted` the executor enforces that default; under\n`passthrough_openai` the field is forwarded verbatim and OpenAI\napplies its own default." } ] }, "server_description": { "type": [ "string", "null" ], "description": "Human-readable description surfaced to the model." }, "server_label": { "type": "string", "description": "Stable identifier surfaced in `mcp_list_tools` and `mcp_call`\nitems. Required even when using `connector_id` so output items\nhave a consistent label." }, "server_url": { "type": [ "string", "null" ], "description": "URL of the remote MCP server (Streamable HTTP). Mutually\nexclusive with `connector_id`." }, "type": { "$ref": "#/components/schemas/McpToolType" } } }, "McpToolFilter": { "type": "object", "description": "Spec `MCPToolFilter`: a set of tool names plus an optional\n`read_only` predicate that matches tools whose MCP `readOnlyHint`\nannotation is true. Either field is optional; both are AND-combined\n(tool name must be in `tool_names` *and* `read_only` must match if set).", "properties": { "read_only": { "type": [ "boolean", "null" ], "description": "Restrict to tools whose annotation `readOnlyHint == true`.\n`None` means don't filter on this property." }, "tool_names": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Tool names to include. Omit to match any name." } }, "additionalProperties": false }, "McpToolType": { "type": "string", "enum": [ "mcp" ] }, "MeResponse": { "type": "object", "description": "Response for the /auth/me endpoint.", "required": [ "external_id", "roles", "idp_groups" ], "properties": { "email": { "type": [ "string", "null" ] }, "external_id": { "type": "string" }, "idp_groups": { "type": "array", "items": { "type": "string" }, "description": "Raw IdP groups from the authentication source.\nThese are the exact values from the IdP (e.g., OIDC groups claim),\nbefore any mapping or transformation. Useful for debugging SSO group mappings." }, "name": { "type": [ "string", "null" ] }, "roles": { "type": "array", "items": { "type": "string" }, "description": "User's roles (e.g., super_admin, org_admin, team_admin, user)" }, "user_id": { "type": [ "string", "null" ], "format": "uuid" } } }, "MembershipSource": { "type": "string", "description": "Source of a membership (how it was created).\n\nThis enum tracks the origin of org, team, and project memberships,\nwhich is critical for `sync_memberships_on_login` to work correctly.\nJIT-created memberships can be removed when no longer present in IdP groups,\nwhile manual and SCIM memberships are preserved.", "enum": [ "manual", "jit", "scim" ] }, "Message": { "type": "object", "description": "A chat message in a conversation", "required": [ "role", "content" ], "properties": { "content": { "type": "string" }, "role": { "type": "string" } } }, "MessageContent": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "$ref": "#/components/schemas/ContentPart" } } ], "description": "Message content (text or multimodal parts)" }, "ModelPricingListResponse": { "type": "object", "description": "Paginated list of model pricing entries", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/DbModelPricing" }, "description": "List of model pricing entries" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "ModelSpendResponse": { "type": "object", "description": "Usage breakdown by model", "required": [ "model", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Audio duration in seconds" }, "character_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Character count (TTS input)" }, "image_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Number of images generated" }, "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens used by this model" }, "model": { "type": "string", "description": "Model name" }, "output_tokens": { "type": "integer", "format": "int64", "description": "Output tokens used by this model" }, "request_count": { "type": "integer", "format": "int64", "description": "Number of requests to this model" }, "total_cost": { "type": "number", "format": "double", "description": "Total cost in dollars for this model" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens used by this model" } } }, "NamedToolChoice": { "type": "object", "description": "Named tool choice", "required": [ "type", "function" ], "properties": { "function": { "$ref": "#/components/schemas/NamedToolChoiceFunction" }, "type": { "$ref": "#/components/schemas/ToolType" } } }, "NamedToolChoiceFunction": { "type": "object", "description": "Named tool choice function reference", "required": [ "name" ], "properties": { "name": { "type": "string" } } }, "NeverActiveUserEntry": { "type": "object", "description": "A user with access who has never had any recorded activity", "required": [ "user_id", "external_id", "created_at", "days_since_creation", "org_count", "project_count", "active_api_keys" ], "properties": { "active_api_keys": { "type": "integer", "format": "int64", "description": "Number of active API keys" }, "created_at": { "type": "string", "format": "date-time", "description": "When the user was created" }, "days_since_creation": { "type": "integer", "format": "int64", "description": "Days since account creation" }, "email": { "type": [ "string", "null" ], "description": "User's email (if available)" }, "external_id": { "type": "string", "description": "User's external identifier" }, "name": { "type": [ "string", "null" ], "description": "User's name (if available)" }, "org_count": { "type": "integer", "format": "int64", "description": "Number of organization memberships" }, "project_count": { "type": "integer", "format": "int64", "description": "Number of project memberships" }, "user_id": { "type": "string", "format": "uuid", "description": "User ID" } } }, "OAuthKeyOptions": { "type": "object", "description": "User-chosen options for the API key that will be issued when the external\napp redeems the code. Mirrors the fields the self-service \"Create API\nKey\" modal exposes; `owner` is implied from the consenting user.\n\nAll fields are optional — the consent page populates whichever ones the\nuser filled in, and the token endpoint applies them to the issued key.", "properties": { "allowed_models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Allowed model patterns. `None` = all models." }, "budget_limit_cents": { "type": [ "integer", "null" ], "format": "int64", "description": "Spending cap in cents. `None` or `0` means unlimited." }, "budget_period": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/BudgetPeriod", "description": "Period the budget resets over. Required when `budget_limit_cents` is set." } ] }, "expires_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Optional expiration timestamp for the issued API key." }, "ip_allowlist": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "IP/CIDR allowlist. `None` = all IPs." }, "name": { "type": [ "string", "null" ], "description": "Friendly label for the issued key. Falls back to `app_name` then\n`\"OAuth app\"` when empty." }, "owner": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ApiKeyOwner", "description": "Owner the issued key should belong to. Defaults to the consenting\nuser. The authorize endpoint validates that the user has permission\nto create keys for the chosen owner using the same RBAC rules as the\nadmin \"Create API Key\" endpoint." } ] }, "rate_limit_rpm": { "type": [ "integer", "null" ], "format": "int32", "description": "Per-key requests-per-minute override." }, "rate_limit_tpm": { "type": [ "integer", "null" ], "format": "int32", "description": "Per-key tokens-per-minute override." }, "scopes": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Permission scopes (e.g. `chat`, `embeddings`). `None` = full access." }, "sovereignty_requirements": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyRequirements", "description": "Sovereignty requirements for model access." } ] } } }, "OAuthTokenResponse": { "type": "object", "description": "Response from `POST /oauth/token`. Mirrors OpenRouter's shape so that\nexisting client libraries written against their PKCE flow drop in.", "required": [ "key", "key_prefix", "key_id" ], "properties": { "key": { "type": "string", "description": "The newly-issued API key. Only returned once — store it securely." }, "key_id": { "type": "string", "format": "uuid", "description": "ID of the API key record, for revocation via the admin API." }, "key_prefix": { "type": "string", "description": "User-facing prefix of the key (e.g. `gw_abc...`). Useful for display." } } }, "OrgAccessEntry": { "type": "object", "description": "Organization access entry for access reviews", "required": [ "org_id", "org_slug", "org_name", "role", "granted_at" ], "properties": { "granted_at": { "type": "string", "format": "date-time", "description": "When the user was granted access (joined)" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization ID" }, "org_name": { "type": "string", "description": "Organization name" }, "org_slug": { "type": "string", "description": "Organization slug" }, "role": { "type": "string", "description": "User's role in the organization" } } }, "OrgAccessReportQuery": { "type": "object", "description": "Query parameters for organization access report endpoint", "properties": { "format": { "$ref": "#/components/schemas/ExportFormat", "description": "Export format (json or csv)" } } }, "OrgAccessReportResponse": { "type": "object", "description": "Organization access report response", "required": [ "generated_at", "org_id", "org_slug", "org_name", "members", "api_keys", "access_history", "summary" ], "properties": { "access_history": { "type": "array", "items": { "$ref": "#/components/schemas/AccessGrantHistoryEntry" }, "description": "Recent access grant history from audit logs" }, "api_keys": { "type": "array", "items": { "$ref": "#/components/schemas/OrgApiKeyEntry" }, "description": "All API keys scoped to this organization or its projects" }, "generated_at": { "type": "string", "format": "date-time", "description": "When this report was generated" }, "members": { "type": "array", "items": { "$ref": "#/components/schemas/OrgMemberAccessEntry" }, "description": "All members with their access details" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization ID" }, "org_name": { "type": "string", "description": "Organization name" }, "org_slug": { "type": "string", "description": "Organization slug" }, "summary": { "$ref": "#/components/schemas/OrgAccessReportSummary", "description": "Summary statistics" } } }, "OrgAccessReportSummary": { "type": "object", "description": "Summary statistics for organization access report", "required": [ "total_members", "total_projects", "total_project_memberships", "active_api_keys", "revoked_api_keys" ], "properties": { "active_api_keys": { "type": "integer", "format": "int64", "description": "Total number of active API keys" }, "revoked_api_keys": { "type": "integer", "format": "int64", "description": "Total number of revoked API keys" }, "total_members": { "type": "integer", "format": "int64", "description": "Total number of org members" }, "total_project_memberships": { "type": "integer", "format": "int64", "description": "Total number of project memberships" }, "total_projects": { "type": "integer", "format": "int64", "description": "Total number of projects in the org" } } }, "OrgApiKeyEntry": { "type": "object", "description": "API key entry for organization access reports", "required": [ "key_id", "name", "key_prefix", "owner_type", "owner_id", "is_active", "created_at" ], "properties": { "created_at": { "type": "string", "format": "date-time", "description": "When the key was created" }, "expires_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the key expires (if set)" }, "is_active": { "type": "boolean", "description": "Whether the key is currently active" }, "key_id": { "type": "string", "format": "uuid", "description": "API key ID" }, "key_prefix": { "type": "string", "description": "Key prefix for identification" }, "last_used_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the key was last used" }, "name": { "type": "string", "description": "API key name" }, "owner_id": { "type": "string", "format": "uuid", "description": "Owner ID" }, "owner_type": { "type": "string", "description": "Owner type (organization, project, or user)" }, "project_slug": { "type": [ "string", "null" ], "description": "Project slug if scoped to a project" }, "revoked_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the key was revoked (if revoked)" }, "user_email": { "type": [ "string", "null" ], "description": "User email (if user-owned)" }, "user_id": { "type": [ "string", "null" ], "format": "uuid", "description": "User who owns the key (if user-owned)" } } }, "OrgMemberAccessEntry": { "type": "object", "description": "Member access entry for organization access reports", "required": [ "user_id", "external_id", "role", "granted_at", "project_access", "api_key_summary" ], "properties": { "api_key_summary": { "$ref": "#/components/schemas/ApiKeySummary", "description": "API key summary for keys scoped to this org/projects" }, "email": { "type": [ "string", "null" ], "description": "User's email (if available)" }, "external_id": { "type": "string", "description": "User's external identifier (e.g., from SSO)" }, "granted_at": { "type": "string", "format": "date-time", "description": "When the user was granted access to the organization" }, "last_activity_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last activity timestamp within this org" }, "name": { "type": [ "string", "null" ], "description": "User's name (if available)" }, "project_access": { "type": "array", "items": { "$ref": "#/components/schemas/OrgMemberProjectAccess" }, "description": "Projects within this org that the user has access to" }, "role": { "type": "string", "description": "User's role in the organization" }, "user_id": { "type": "string", "format": "uuid", "description": "User ID" } } }, "OrgMemberProjectAccess": { "type": "object", "description": "Project access within an organization for a member", "required": [ "project_id", "project_slug", "project_name", "role", "granted_at" ], "properties": { "granted_at": { "type": "string", "format": "date-time", "description": "When the user was granted access to this project" }, "project_id": { "type": "string", "format": "uuid", "description": "Project ID" }, "project_name": { "type": "string", "description": "Project name" }, "project_slug": { "type": "string", "description": "Project slug" }, "role": { "type": "string", "description": "User's role in the project" } } }, "OrgMembershipInfo": { "type": "object", "description": "Organization membership information.", "required": [ "org_id", "org_slug", "org_name", "role", "joined_at" ], "properties": { "joined_at": { "type": "string", "format": "date-time", "description": "When the membership was created" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization ID" }, "org_name": { "type": "string", "description": "Organization name" }, "org_slug": { "type": "string", "description": "Organization slug" }, "role": { "type": "string", "description": "User's role in this organization" } } }, "OrgRbacPolicy": { "type": "object", "description": "Organization RBAC Policy.\n\nPer-organization authorization policy that uses CEL expressions for evaluation.\nPolicies are evaluated in priority order (highest first) and the first matching\npolicy determines the access decision.", "required": [ "id", "org_id", "name", "resource", "action", "condition", "effect", "priority", "enabled", "version", "created_at", "updated_at" ], "properties": { "action": { "type": "string", "description": "Action pattern to match (e.g., \"read\", \"write\", \"delete\", \"*\")" }, "condition": { "type": "string", "description": "CEL expression that must evaluate to true for the policy to apply" }, "created_at": { "type": "string", "format": "date-time", "description": "When this policy was created" }, "deleted_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When this policy was soft-deleted (None if active)" }, "description": { "type": [ "string", "null" ], "description": "Optional description of what this policy does" }, "effect": { "$ref": "#/components/schemas/RbacPolicyEffect", "description": "Policy effect when condition matches" }, "enabled": { "type": "boolean", "description": "Whether this policy is active" }, "id": { "type": "string", "format": "uuid", "description": "Unique identifier for this policy" }, "name": { "type": "string", "description": "Human-readable name for this policy (unique per org among non-deleted policies)" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization this policy belongs to" }, "priority": { "type": "integer", "format": "int32", "description": "Priority for evaluation order (higher = evaluated first)" }, "resource": { "type": "string", "description": "Resource pattern to match (e.g., \"projects/*\", \"teams/engineering/*\", \"*\")" }, "updated_at": { "type": "string", "format": "date-time", "description": "When this policy was last updated" }, "version": { "type": "integer", "format": "int32", "description": "Version number (incremented on each update)" } } }, "OrgRbacPolicyListResponse": { "type": "object", "description": "Paginated list of RBAC policies", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/OrgRbacPolicy" }, "description": "List of RBAC policies" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "OrgRbacPolicyVersion": { "type": "object", "description": "Version history record for an RBAC policy.\n\nEvery update to a policy creates a new version record, enabling audit\ntrails and rollback to previous configurations.", "required": [ "id", "policy_id", "version", "name", "resource", "action", "condition", "effect", "priority", "enabled", "created_at" ], "properties": { "action": { "type": "string", "description": "Action pattern at this version" }, "condition": { "type": "string", "description": "CEL condition at this version" }, "created_at": { "type": "string", "format": "date-time", "description": "When this version was created" }, "created_by": { "type": [ "string", "null" ], "format": "uuid", "description": "User who created this version (if known)" }, "description": { "type": [ "string", "null" ], "description": "Policy description at this version" }, "effect": { "$ref": "#/components/schemas/RbacPolicyEffect", "description": "Policy effect at this version" }, "enabled": { "type": "boolean", "description": "Enabled state at this version" }, "id": { "type": "string", "format": "uuid", "description": "Unique identifier for this version record" }, "name": { "type": "string", "description": "Policy name at this version" }, "policy_id": { "type": "string", "format": "uuid", "description": "The policy this version belongs to" }, "priority": { "type": "integer", "format": "int32", "description": "Priority at this version" }, "reason": { "type": [ "string", "null" ], "description": "Reason for the change" }, "resource": { "type": "string", "description": "Resource pattern at this version" }, "version": { "type": "integer", "format": "int32", "description": "Version number (matches the policy's version at time of creation)" } } }, "OrgRbacPolicyVersionListResponse": { "type": "object", "description": "Paginated list of RBAC policy versions", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/OrgRbacPolicyVersion" }, "description": "List of policy versions" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "OrgScimConfig": { "type": "object", "description": "Per-organization SCIM configuration.\n\nEnables automatic user provisioning/deprovisioning from identity providers.\nEach organization can have at most one SCIM configuration.", "required": [ "id", "org_id", "enabled", "token_prefix", "create_users", "default_org_role", "default_team_role", "sync_display_name", "deactivate_deletes_user", "revoke_api_keys_on_deactivate", "created_at", "updated_at" ], "properties": { "create_users": { "type": "boolean", "description": "Whether to create new users when they don't exist" }, "created_at": { "type": "string", "format": "date-time", "description": "When this config was created" }, "deactivate_deletes_user": { "type": "boolean", "description": "Whether deactivating a user deletes them entirely (vs just marking inactive)" }, "default_org_role": { "type": "string", "description": "Default role for new users in the organization" }, "default_team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Default team to add new users to (optional)" }, "default_team_role": { "type": "string", "description": "Default role for new users in the default team" }, "enabled": { "type": "boolean", "description": "Whether SCIM provisioning is enabled" }, "id": { "type": "string", "format": "uuid", "description": "Unique identifier for this SCIM configuration" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization this SCIM config belongs to (one config per org)" }, "revoke_api_keys_on_deactivate": { "type": "boolean", "description": "Whether to revoke all API keys when a user is deactivated via SCIM" }, "sync_display_name": { "type": "boolean", "description": "Whether to sync display name from SCIM on updates" }, "token_last_used_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last time the SCIM token was used for authentication" }, "token_prefix": { "type": "string", "description": "Token prefix for identification (first 8 chars, like 'scim_xxxx')\nNote: token_hash is NOT included in the model - it's stored separately" }, "updated_at": { "type": "string", "format": "date-time", "description": "When this config was last updated" } } }, "OrgSpendResponse": { "type": "object", "description": "Usage breakdown by organization", "required": [ "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64" }, "character_count": { "type": "integer", "format": "int64" }, "image_count": { "type": "integer", "format": "int64" }, "input_tokens": { "type": "integer", "format": "int64" }, "org_id": { "type": [ "string", "null" ] }, "org_name": { "type": [ "string", "null" ] }, "output_tokens": { "type": "integer", "format": "int64" }, "request_count": { "type": "integer", "format": "int64" }, "total_cost": { "type": "number", "format": "double" }, "total_tokens": { "type": "integer", "format": "int64" } } }, "OrgSsoConfig": { "type": "object", "description": "Organization SSO Configuration.\n\nStores per-organization OIDC or SAML configuration for multi-tenant SSO.\nEach organization can have its own IdP, enabling IT admins to configure\ntheir own identity provider via the Admin UI.", "required": [ "id", "org_id", "provider_type", "scopes", "saml_sign_requests", "saml_force_authn", "provisioning_enabled", "create_users", "default_org_role", "default_team_role", "allowed_email_domains", "sync_attributes_on_login", "sync_memberships_on_login", "enforcement_mode", "enabled", "created_at", "updated_at" ], "properties": { "allowed_email_domains": { "type": "array", "items": { "type": "string" }, "description": "Allowed email domains (empty = allow all)" }, "client_id": { "type": [ "string", "null" ], "description": "OAuth2 client ID (required for OIDC, not used for SAML)" }, "create_users": { "type": "boolean", "description": "Whether to create new users on first login" }, "created_at": { "type": "string", "format": "date-time", "description": "When this config was created" }, "default_org_role": { "type": "string", "description": "Default role for new users in the organization" }, "default_team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Default team to add new users to (optional)" }, "default_team_role": { "type": "string", "description": "Default role for new users in the default team" }, "discovery_url": { "type": [ "string", "null" ], "description": "Discovery URL for OIDC metadata (defaults to issuer/.well-known/openid-configuration)" }, "enabled": { "type": "boolean", "description": "Whether this SSO config is active" }, "enforcement_mode": { "$ref": "#/components/schemas/SsoEnforcementMode", "description": "SSO enforcement mode (optional, required, or test)" }, "groups_claim": { "type": [ "string", "null" ], "description": "JWT claim containing group memberships (optional, OIDC only)" }, "id": { "type": "string", "format": "uuid", "description": "Unique identifier for this SSO configuration" }, "identity_claim": { "type": [ "string", "null" ], "description": "JWT claim to use as the user's identity (default: \"sub\")\nRequired for OIDC, not used for SAML (use saml_identity_attribute instead)" }, "issuer": { "type": [ "string", "null" ], "description": "OIDC issuer URL (e.g., \"https://accounts.google.com\")\nRequired for OIDC, not used for SAML" }, "org_claim": { "type": [ "string", "null" ], "description": "JWT claim containing organization IDs (optional, OIDC only)" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization this SSO config belongs to (one config per org)" }, "provider_type": { "$ref": "#/components/schemas/SsoProviderType", "description": "Provider type (oidc or saml)" }, "provisioning_enabled": { "type": "boolean", "description": "Whether JIT provisioning is enabled for this SSO config" }, "redirect_uri": { "type": [ "string", "null" ], "description": "Redirect URI for OAuth2 callback (optional - uses global default if not set)" }, "saml_authn_context_class_ref": { "type": [ "string", "null" ], "description": "Requested authentication context class" }, "saml_email_attribute": { "type": [ "string", "null" ], "description": "SAML attribute name for email" }, "saml_force_authn": { "type": "boolean", "description": "Whether to force re-authentication at IdP" }, "saml_groups_attribute": { "type": [ "string", "null" ], "description": "SAML attribute name for groups" }, "saml_identity_attribute": { "type": [ "string", "null" ], "description": "SAML attribute name for user identity (like identity_claim for OIDC)" }, "saml_idp_certificate": { "type": [ "string", "null" ], "description": "IdP X.509 certificate for signature validation (PEM format)" }, "saml_idp_entity_id": { "type": [ "string", "null" ], "description": "IdP entity identifier (e.g., \"https://idp.example.com/metadata\")" }, "saml_idp_slo_url": { "type": [ "string", "null" ], "description": "IdP Single Logout service URL (optional)" }, "saml_idp_sso_url": { "type": [ "string", "null" ], "description": "IdP Single Sign-On service URL (HTTP-Redirect or HTTP-POST binding)" }, "saml_metadata_url": { "type": [ "string", "null" ], "description": "IdP metadata URL for auto-configuration (alternative to manual config)" }, "saml_name_attribute": { "type": [ "string", "null" ], "description": "SAML attribute name for display name" }, "saml_name_id_format": { "type": [ "string", "null" ], "description": "NameID format to request (e.g., 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress')" }, "saml_sign_requests": { "type": "boolean", "description": "Whether to sign AuthnRequests" }, "saml_sp_certificate": { "type": [ "string", "null" ], "description": "SP X.509 certificate for SP metadata (PEM format)\nInclude when request signing is enabled so IdPs can verify signatures" }, "saml_sp_entity_id": { "type": [ "string", "null" ], "description": "Service Provider entity ID (Hadrian's identifier to the IdP)" }, "scopes": { "type": "array", "items": { "type": "string" }, "description": "OAuth2 scopes to request (e.g., [\"openid\", \"email\", \"profile\"])\nEmpty for SAML configs" }, "sync_attributes_on_login": { "type": "boolean", "description": "Whether to sync user attributes (email, name) on each login" }, "sync_memberships_on_login": { "type": "boolean", "description": "Whether to sync team memberships from IdP groups on each login" }, "updated_at": { "type": "string", "format": "date-time", "description": "When this config was last updated" } } }, "Organization": { "type": "object", "required": [ "id", "slug", "name", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "slug": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "OrganizationListResponse": { "type": "object", "description": "Paginated list of organizations", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Organization" }, "description": "List of organizations" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "PaginationMeta": { "type": "object", "description": "Pagination metadata for list responses using cursor-based pagination.\n\nCursor-based pagination provides stable, performant navigation for large datasets.\nUse `next_cursor` and `prev_cursor` to navigate between pages.", "required": [ "limit", "has_more" ], "properties": { "has_more": { "type": "boolean", "description": "Whether there are more records available after this page.", "example": true }, "limit": { "type": "integer", "format": "int64", "description": "Maximum number of records returned per page.", "example": 100 }, "next_cursor": { "type": [ "string", "null" ], "description": "Cursor for fetching the next page.", "example": "MTczMzU4MDgwMDAwMDphYmMxMjM0NS02Nzg5LTAxMjMtNDU2Ny0wMTIzNDU2Nzg5YWI" }, "prev_cursor": { "type": [ "string", "null" ], "description": "Cursor for fetching the previous page." } } }, "ParseSamlMetadataRequest": { "type": "object", "description": "Request to parse SAML IdP metadata from a URL.", "required": [ "metadata_url" ], "properties": { "metadata_url": { "type": "string", "description": "URL to fetch IdP metadata from (must be HTTPS for security)" } } }, "ParsedSamlIdpConfig": { "type": "object", "description": "Parsed SAML IdP configuration extracted from metadata.\n\nThis is returned for admin review before saving - use the individual fields\nto populate the SSO config.", "required": [ "entity_id", "sso_url", "certificates", "name_id_formats" ], "properties": { "certificates": { "type": "array", "items": { "type": "string" }, "description": "X.509 certificates for signature verification (PEM format)\nMultiple certificates may be present for key rollover" }, "entity_id": { "type": "string", "description": "IdP entity identifier" }, "name_id_formats": { "type": "array", "items": { "type": "string" }, "description": "Supported NameID formats" }, "slo_url": { "type": [ "string", "null" ], "description": "IdP Single Logout service URL (if available)" }, "sso_url": { "type": "string", "description": "IdP Single Sign-On service URL" } } }, "PartialImages": { "type": "object", "description": "Partial images configuration for streaming", "properties": { "partial_image_count": { "type": [ "integer", "null" ], "format": "int32", "description": "Number of partial images to generate during streaming" } } }, "PkceCodeChallengeMethod": { "type": "string", "description": "PKCE code challenge method supplied by the external app.", "enum": [ "S256", "plain" ] }, "PolicyEvaluationResult": { "type": "object", "description": "Result of evaluating a single policy", "required": [ "name", "source", "pattern_matched", "effect", "priority" ], "properties": { "condition_matched": { "type": [ "boolean", "null" ], "description": "Whether the policy's CEL condition evaluated to true" }, "description": { "type": [ "string", "null" ], "description": "Policy description" }, "effect": { "$ref": "#/components/schemas/RbacPolicyEffect", "description": "Policy effect (allow/deny)" }, "error": { "type": [ "string", "null" ], "description": "Error message if condition evaluation failed" }, "id": { "type": [ "string", "null" ], "format": "uuid", "description": "Policy ID (None for system policies)" }, "name": { "type": "string", "description": "Policy name" }, "pattern_matched": { "type": "boolean", "description": "Whether the policy's resource/action pattern matched" }, "priority": { "type": "integer", "format": "int32", "description": "Policy priority" }, "skipped_reason": { "type": [ "string", "null" ], "description": "Reason why condition was not evaluated (e.g., \"Policy is disabled\")" }, "source": { "$ref": "#/components/schemas/PolicySource", "description": "Source of this policy (system or organization)" } } }, "PolicySource": { "type": "string", "description": "Source of an RBAC policy (system config vs organization database)", "enum": [ "system", "organization" ] }, "PreflightResponse": { "type": "object", "description": "Result of the preflight check.", "required": [ "callback_host" ], "properties": { "callback_host": { "type": "string", "description": "The validated host (lowercased) — useful for surfacing in the UI." } } }, "PricingOwner": { "oneOf": [ { "type": "object", "description": "Global pricing (no specific owner)", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "global" ] } } }, { "type": "object", "description": "Organization-scoped pricing", "required": [ "org_id", "type" ], "properties": { "org_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "organization" ] } } }, { "type": "object", "description": "Team-scoped pricing", "required": [ "team_id", "type" ], "properties": { "team_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "team" ] } } }, { "type": "object", "description": "Project-scoped pricing", "required": [ "project_id", "type" ], "properties": { "project_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "project" ] } } }, { "type": "object", "description": "User-scoped pricing", "required": [ "user_id", "type" ], "properties": { "type": { "type": "string", "enum": [ "user" ] }, "user_id": { "type": "string", "format": "uuid" } } } ], "description": "Owner scope for model pricing configuration" }, "PricingSource": { "type": "string", "description": "Source of pricing data", "enum": [ "manual", "provider_api", "default" ] }, "PricingSourceSpendResponse": { "type": "object", "description": "Usage breakdown by pricing source", "required": [ "pricing_source", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Audio duration in seconds" }, "character_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Character count (TTS input)" }, "image_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Number of images generated" }, "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens" }, "output_tokens": { "type": "integer", "format": "int64", "description": "Output tokens" }, "pricing_source": { "type": "string", "description": "Pricing source (provider, provider_config, pricing_config, catalog, none)" }, "request_count": { "type": "integer", "format": "int64", "description": "Number of requests" }, "total_cost": { "type": "number", "format": "double", "description": "Total cost in dollars for this pricing source" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens" } } }, "Project": { "type": "object", "required": [ "id", "org_id", "slug", "name", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "org_id": { "type": "string", "format": "uuid" }, "slug": { "type": "string" }, "team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Team this project belongs to (optional)" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ProjectAccessEntry": { "type": "object", "description": "Project access entry for access reviews", "required": [ "project_id", "project_slug", "project_name", "org_id", "org_slug", "role", "granted_at" ], "properties": { "granted_at": { "type": "string", "format": "date-time", "description": "When the user was granted access (joined)" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization ID the project belongs to" }, "org_slug": { "type": "string", "description": "Organization slug the project belongs to" }, "project_id": { "type": "string", "format": "uuid", "description": "Project ID" }, "project_name": { "type": "string", "description": "Project name" }, "project_slug": { "type": "string", "description": "Project slug" }, "role": { "type": "string", "description": "User's role in the project" } } }, "ProjectListResponse": { "type": "object", "description": "Paginated list of projects", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Project" }, "description": "List of projects" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "ProjectMembershipInfo": { "type": "object", "description": "Project membership information.", "required": [ "project_id", "project_slug", "project_name", "org_slug", "role", "joined_at" ], "properties": { "joined_at": { "type": "string", "format": "date-time", "description": "When the membership was created" }, "org_slug": { "type": "string", "description": "Organization the project belongs to" }, "project_id": { "type": "string", "format": "uuid", "description": "Project ID" }, "project_name": { "type": "string", "description": "Project name" }, "project_slug": { "type": "string", "description": "Project slug" }, "role": { "type": "string", "description": "User's role in this project" } } }, "ProjectSpendResponse": { "type": "object", "description": "Usage breakdown by project", "required": [ "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64" }, "character_count": { "type": "integer", "format": "int64" }, "image_count": { "type": "integer", "format": "int64" }, "input_tokens": { "type": "integer", "format": "int64" }, "output_tokens": { "type": "integer", "format": "int64" }, "project_id": { "type": [ "string", "null" ] }, "project_name": { "type": [ "string", "null" ] }, "request_count": { "type": "integer", "format": "int64" }, "total_cost": { "type": "number", "format": "double" }, "total_tokens": { "type": "integer", "format": "int64" } } }, "ProviderCircuitBreakerResponse": { "type": "object", "description": "Response for a single provider's circuit breaker status.", "required": [ "provider", "state", "failure_count" ], "properties": { "failure_count": { "type": "integer", "format": "int32", "description": "Number of consecutive failures (only relevant in Closed state).", "minimum": 0 }, "provider": { "type": "string", "description": "Provider name." }, "state": { "type": "string", "description": "Circuit breaker state (closed, open, half_open)." } } }, "ProviderHealthResponse": { "type": "object", "description": "Response for provider health status endpoint.", "required": [ "providers" ], "properties": { "providers": { "type": "array", "items": { "$ref": "#/components/schemas/ProviderHealthState" }, "description": "List of health states for all providers with health checks enabled." } } }, "ProviderHealthState": { "type": "object", "description": "Stored health state for a single provider.", "required": [ "provider", "status", "latency_ms", "last_check", "consecutive_failures", "consecutive_successes" ], "properties": { "consecutive_failures": { "type": "integer", "format": "int32", "description": "Number of consecutive failures.", "minimum": 0 }, "consecutive_successes": { "type": "integer", "format": "int32", "description": "Number of consecutive successes.", "minimum": 0 }, "error": { "type": [ "string", "null" ], "description": "Error message from the last failed health check." }, "last_check": { "type": "string", "format": "date-time", "description": "Time of the last health check." }, "latency_ms": { "type": "integer", "format": "int64", "description": "Latency of the last health check in milliseconds.", "minimum": 0 }, "provider": { "type": "string", "description": "Provider name." }, "status": { "$ref": "#/components/schemas/HealthStatus", "description": "Current health status." }, "status_code": { "type": [ "integer", "null" ], "format": "int32", "description": "HTTP status code from the last health check.", "minimum": 0 } } }, "ProviderOwner": { "oneOf": [ { "type": "object", "required": [ "org_id", "type" ], "properties": { "org_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "organization" ] } } }, { "type": "object", "required": [ "team_id", "type" ], "properties": { "team_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "team" ] } } }, { "type": "object", "required": [ "project_id", "type" ], "properties": { "project_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "project" ] } } }, { "type": "object", "required": [ "user_id", "type" ], "properties": { "type": { "type": "string", "enum": [ "user" ] }, "user_id": { "type": "string", "format": "uuid" } } } ], "description": "Owner of a dynamic provider" }, "ProviderSpendResponse": { "type": "object", "description": "Usage breakdown by provider", "required": [ "provider", "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Audio duration in seconds" }, "character_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Character count (TTS input)" }, "image_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Number of images generated" }, "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens used by this provider" }, "output_tokens": { "type": "integer", "format": "int64", "description": "Output tokens used by this provider" }, "provider": { "type": "string", "description": "Provider name" }, "request_count": { "type": "integer", "format": "int64", "description": "Number of requests to this provider" }, "total_cost": { "type": "number", "format": "double", "description": "Total cost in dollars for this provider" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens used by this provider" } } }, "ProviderStats": { "type": "object", "description": "Current aggregated statistics for a provider.", "required": [ "provider", "request_count", "error_count", "input_tokens", "output_tokens", "total_cost_microcents", "last_updated" ], "properties": { "avg_latency_ms": { "type": [ "number", "null" ], "format": "double", "description": "Average latency in milliseconds" }, "error_count": { "type": "integer", "format": "int64", "description": "Total number of error responses (status != success)" }, "errors_by_status": { "type": "object", "description": "Error counts broken down by HTTP status code", "additionalProperties": { "type": "integer", "format": "int64" }, "propertyNames": { "type": "integer", "format": "int32", "minimum": 0 } }, "input_tokens": { "type": "integer", "format": "int64", "description": "Total input tokens consumed" }, "last_updated": { "type": "string", "format": "date-time", "description": "When these stats were last updated" }, "output_tokens": { "type": "integer", "format": "int64", "description": "Total output tokens generated" }, "p50_latency_ms": { "type": [ "number", "null" ], "format": "double", "description": "50th percentile latency in milliseconds" }, "p95_latency_ms": { "type": [ "number", "null" ], "format": "double", "description": "95th percentile latency in milliseconds" }, "p99_latency_ms": { "type": [ "number", "null" ], "format": "double", "description": "99th percentile latency in milliseconds" }, "provider": { "type": "string", "description": "Provider name" }, "request_count": { "type": "integer", "format": "int64", "description": "Total number of requests" }, "total_cost_microcents": { "type": "integer", "format": "int64", "description": "Total cost in microcents" } } }, "ProviderStatsHistorical": { "type": "object", "description": "Historical stats response containing multiple time buckets.", "required": [ "provider", "granularity", "data" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/TimeBucketStats" }, "description": "Time series data points" }, "granularity": { "$ref": "#/components/schemas/StatsGranularity", "description": "Granularity of the buckets" }, "prometheus_configured": { "type": "boolean", "description": "Whether Prometheus is configured for historical metrics.\nWhen false, the `data` array will be empty because historical\nstats require Prometheus to be configured." }, "provider": { "type": "string", "description": "Provider name" } } }, "ProviderStatsHistoryQuery": { "type": "object", "description": "Query parameters for historical stats.", "properties": { "end": { "type": [ "string", "null" ], "format": "date-time", "description": "End of the time range (defaults to now)." }, "granularity": { "type": [ "string", "null" ], "description": "Granularity of the data points: \"hour\" or \"day\" (defaults to \"hour\")." }, "start": { "type": [ "string", "null" ], "format": "date-time", "description": "Start of the time range (defaults to 24 hours ago)." } } }, "ProviderStatsResponse": { "type": "object", "description": "Response for provider stats endpoint.", "required": [ "stats" ], "properties": { "stats": { "type": "array", "items": { "$ref": "#/components/schemas/ProviderStats" }, "description": "List of stats for all providers." } } }, "PruneQuery": { "type": "object", "description": "Prune old DLQ entries based on age.", "properties": { "older_than_secs": { "type": [ "integer", "null" ], "format": "int64", "description": "Prune entries older than this many seconds (default: TTL from config).", "minimum": 0 } } }, "RbacPolicyEffect": { "type": "string", "description": "RBAC policy effect.\n\nDetermines whether a matching policy allows or denies access.", "enum": [ "allow", "deny" ] }, "ReasoningEffort": { "type": "string", "description": "Reasoning effort level", "enum": [ "none", "minimal", "low", "medium", "high" ] }, "ReasoningSummary": { "type": "string", "description": "Reasoning summary format", "enum": [ "auto", "concise", "detailed" ] }, "RefererSpendResponse": { "type": "object", "description": "Usage breakdown by HTTP referer", "required": [ "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Audio duration in seconds" }, "character_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Character count (TTS input)" }, "http_referer": { "type": [ "string", "null" ], "description": "HTTP referer header value" }, "image_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Number of images generated" }, "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens used from this referer" }, "output_tokens": { "type": "integer", "format": "int64", "description": "Output tokens used from this referer" }, "request_count": { "type": "integer", "format": "int64", "description": "Number of requests from this referer" }, "total_cost": { "type": "number", "format": "double", "description": "Total cost in dollars from this referer" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens used from this referer" } } }, "ResponseFormat": { "oneOf": [ { "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "text" ] } } }, { "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "json_object" ] } } }, { "type": "object", "required": [ "json_schema", "type" ], "properties": { "json_schema": { "$ref": "#/components/schemas/JsonSchemaConfig" }, "type": { "type": "string", "enum": [ "json_schema" ] } } }, { "type": "object", "required": [ "grammar", "type" ], "properties": { "grammar": { "type": "string" }, "type": { "type": "string", "enum": [ "grammar" ] } } }, { "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "python" ] } } } ], "description": "Response format for chat completion" }, "ResponsesToolDefinition": { "oneOf": [ { "$ref": "#/components/schemas/FileSearchTool" }, { "$ref": "#/components/schemas/WebSearchPreviewTool" }, { "$ref": "#/components/schemas/WebSearchPreview20250311Tool" }, { "$ref": "#/components/schemas/WebSearchTool" }, { "$ref": "#/components/schemas/WebSearch20250826Tool" }, { "$ref": "#/components/schemas/ShellTool" }, { "$ref": "#/components/schemas/McpTool" }, { "$ref": "#/components/schemas/ToolSearchTool" }, { "$ref": "#/components/schemas/FunctionTool" } ], "description": "Tool definition - one of the supported tool variants. The schema\nemits a `oneOf` over the variants; each variant constrains its\n`type` field to a single literal, so consumers (and the OpenAPI\nconformance script) can match variants by `type`. The `Function`\nvariant stays as an opaque `serde_json::Value` at the data level\nso existing rewrite pipelines (web_search → function, shell →\nfunction, MCP → per-tool function) keep constructing it via JSON;\nthe schema reports it as a [`FunctionTool`] for documentation." }, "RollbackOrgRbacPolicy": { "type": "object", "description": "Request to rollback an RBAC policy to a previous version.", "required": [ "target_version" ], "properties": { "reason": { "type": [ "string", "null" ], "description": "Reason for the rollback (stored in version history)" }, "target_version": { "type": "integer", "format": "int32", "description": "Target version number to rollback to" } } }, "RotateApiKeyRequest": { "type": "object", "description": "Request body for rotating an API key", "properties": { "grace_period_seconds": { "type": [ "integer", "null" ], "format": "int64", "description": "Grace period in seconds during which both old and new keys are valid.\nDefault: 86400 (24 hours). Maximum: 604800 (7 days).", "minimum": 0 } } }, "SearchResultItem": { "type": "object", "description": "A single search result.\n\n## Hadrian Extensions\n\nThe following fields are **Hadrian extensions** not present in the standard OpenAI API:\n- `chunk_id`: Unique identifier for the matched chunk\n- `object`: Object type identifier\n- `vector_store_id`: Vector store ID the chunk belongs to\n- `chunk_index`: Position of chunk within the source file\n- `metadata`: Arbitrary metadata (OpenAI uses `attributes`)\n\n## OpenAI Compatibility Notes\n\n- `chunk_id` is serialized with `chunk_` prefix\n- `vector_store_id` is serialized with `vs_` prefix\n- `file_id` is serialized with `file-` prefix\n- `content` is a string; OpenAI uses `content: [{type: \"text\", text: \"...\"}]` array format\n- `filename` is optional; OpenAI requires it\n- `metadata` maps to OpenAI's `attributes` field", "required": [ "chunk_id", "object", "vector_store_id", "file_id", "chunk_index", "content", "score" ], "properties": { "chunk_id": { "type": "string", "description": "**Hadrian Extension:** The chunk ID in the vector store (serialized with `chunk_` prefix)", "example": "chunk_550e8400-e29b-41d4-a716-446655440000" }, "chunk_index": { "type": "integer", "format": "int32", "description": "**Hadrian Extension:** Index of this chunk within the file" }, "content": { "type": "string", "description": "The actual text content of the chunk. Note: OpenAI uses array format `[{type, text}]`." }, "file_id": { "type": "string", "description": "The file this chunk was extracted from (serialized with `file-` prefix)", "example": "file-550e8400-e29b-41d4-a716-446655440000" }, "filename": { "type": [ "string", "null" ], "description": "Filename of the source file. Note: Required in OpenAI, optional in Hadrian." }, "metadata": { "description": "**Hadrian Extension:** Optional additional metadata. Note: OpenAI uses `attributes`." }, "object": { "type": "string", "description": "**Hadrian Extension:** Object type (always \"vector_store.search_result\")" }, "score": { "type": "number", "format": "double", "description": "Similarity score (0.0 to 1.0, higher is more similar)" }, "vector_store_id": { "type": "string", "description": "**Hadrian Extension:** The vector store this chunk belongs to (serialized with `vs_` prefix)", "example": "vs_550e8400-e29b-41d4-a716-446655440000" } } }, "SelfServiceProviderListResponse": { "type": "object", "description": "Paginated list of dynamic providers", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/DynamicProviderResponse" } }, "pagination": { "$ref": "#/components/schemas/PaginationMeta" } } }, "ServiceAccount": { "type": "object", "description": "A service account is a first-class machine identity that can own API keys\nand carry roles for RBAC evaluation. This enables unified authorization\nacross human users and machine identities.", "required": [ "id", "org_id", "slug", "name", "roles", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time", "description": "When the service account was created" }, "description": { "type": [ "string", "null" ], "description": "Optional description" }, "id": { "type": "string", "format": "uuid", "description": "Unique identifier" }, "name": { "type": "string", "description": "Display name" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization this service account belongs to" }, "roles": { "type": "array", "items": { "type": "string" }, "description": "Roles assigned to this service account (used in RBAC evaluation)" }, "slug": { "type": "string", "description": "URL-friendly identifier (unique within org)" }, "updated_at": { "type": "string", "format": "date-time", "description": "When the service account was last updated" } } }, "ServiceAccountListResponse": { "type": "object", "description": "Paginated list of service accounts", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/ServiceAccount" }, "description": "List of service accounts" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "SessionInfo": { "type": "object", "description": "Information about an active user session.", "required": [ "id", "created_at", "expires_at" ], "properties": { "created_at": { "type": "string", "format": "date-time", "description": "When the session was created" }, "device": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/DeviceInfo", "description": "Device information (user agent, IP, description)" } ] }, "expires_at": { "type": "string", "format": "date-time", "description": "When the session will expire" }, "id": { "type": "string", "format": "uuid", "description": "Unique session identifier" }, "last_activity": { "type": [ "string", "null" ], "format": "date-time", "description": "When the session was last active (if tracking enabled)" } } }, "SessionInfoResponse": { "type": "object", "description": "Comprehensive session and access information for debugging.", "required": [ "identity", "organizations", "teams", "projects", "auth_method", "runtime_mode", "server_time" ], "properties": { "auth_method": { "type": "string", "description": "Authentication method used for this session" }, "identity": { "$ref": "#/components/schemas/IdentityInfo", "description": "Identity information from the authentication source" }, "organizations": { "type": "array", "items": { "$ref": "#/components/schemas/OrgMembershipInfo" }, "description": "Organization memberships with roles" }, "projects": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectMembershipInfo" }, "description": "Project access (direct memberships)" }, "runtime_mode": { "type": "string", "description": "Runtime mode: \"server\" for native, \"wasm\" for browser" }, "server_time": { "type": "string", "format": "date-time", "description": "Server timestamp for debugging timezone issues" }, "sso_connection": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SsoConnectionInfo", "description": "SSO connection information (if authenticated via SSO)" } ] }, "teams": { "type": "array", "items": { "$ref": "#/components/schemas/TeamMembershipInfo" }, "description": "Team memberships with roles" }, "user": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/UserInfo", "description": "Database user information (if user exists in database)" } ] } } }, "SessionListResponse": { "type": "object", "description": "Response containing a list of user sessions.", "required": [ "data", "enhanced_enabled" ], "properties": { "current_session_id": { "type": [ "string", "null" ], "format": "uuid", "description": "The session ID of the current request (if authenticated via session cookie).\nAllows the UI to highlight the current session and warn before self-revocation." }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/SessionInfo" }, "description": "List of active sessions for the user" }, "enhanced_enabled": { "type": "boolean", "description": "Whether enhanced session management is enabled.\nIf false, the UI should show a message that session tracking is not enabled." } } }, "SessionsRevokedResponse": { "type": "object", "description": "Response after revoking sessions.", "required": [ "sessions_revoked" ], "properties": { "sessions_revoked": { "type": "integer", "description": "Number of sessions that were revoked", "minimum": 0 } } }, "SetPinOrder": { "type": "object", "description": "Request to set the pin order for a conversation", "properties": { "pin_order": { "type": [ "integer", "null" ], "format": "int32", "description": "The pin order (0 = first, higher = lower in list). Set to null to unpin." } } }, "ShellNetworkPolicy": { "type": "object", "description": "Per-domain egress policy. Matches OpenAI's `network_policy` shape:\n`{ \"type\": \"allowlist\", \"allowed_domains\": [...], \"domain_secrets\": [...] }`.", "properties": { "allowed_domains": { "type": "array", "items": { "type": "string" }, "description": "Hostnames or hostname patterns (`*.example.com`) the container\nmay make outbound requests to. Must be a subset of the\noperator's `allowed_egress_hosts`." }, "domain_secrets": { "type": "array", "items": { "type": "object" }, "description": "Secrets injected for outbound traffic. Accepts either OpenAI's\ninline `{domain, name, value}` form or Hadrian's safer\n`{placeholder, allowed_domains}` reference form — see\n[`ShellDomainSecret`]." }, "type": { "type": "string", "description": "Policy kind. Only `allowlist` is supported today; the field is\nhere for forward compatibility with future OpenAI additions." } }, "additionalProperties": false }, "ShellTool": { "type": "object", "description": "Shell tool — instructs the model that it may call `shell` and the\ngateway will execute the resulting commands in a sandboxed runtime\n(or forward them to the upstream provider's hosted runtime if\nconfigured for passthrough).\n\nMirrors OpenAI's `shell` tool definition for GPT-5.2+. The\n`environment` block lets a caller request narrower constraints than\nthe operator's defaults — anything outside those defaults is\nrejected with `400` at request validation.", "required": [ "type" ], "properties": { "environment": { "type": [ "object", "null" ], "description": "Runtime environment overrides. Every field is a **subset** of\nwhat `[features.server_tools.shell_limits]` permits; requests\nasking for more than the operator allows are rejected." }, "type": { "$ref": "#/components/schemas/ShellToolType" } } }, "ShellToolType": { "type": "string", "enum": [ "shell" ] }, "SimulateContext": { "type": "object", "description": "Context information for policy simulation", "required": [ "resource_type", "action" ], "properties": { "action": { "type": "string", "description": "Action being performed (e.g., \"read\", \"write\", \"delete\", \"*\")" }, "model": { "type": [ "string", "null" ], "description": "Model being requested (for API endpoints, e.g., \"gpt-4o\", \"claude-3-opus\")" }, "org_id": { "type": [ "string", "null" ], "description": "Optional organization ID context" }, "project_id": { "type": [ "string", "null" ], "description": "Optional project ID context" }, "request": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SimulateRequestContext", "description": "Request-specific context (for API endpoints)" } ] }, "resource_id": { "type": [ "string", "null" ], "description": "Optional resource ID" }, "resource_type": { "type": "string", "description": "Resource type being accessed (e.g., \"projects\", \"teams\", \"*\")" }, "team_id": { "type": [ "string", "null" ], "description": "Optional team ID context" } } }, "SimulatePolicyRequest": { "type": "object", "description": "Request to simulate policy evaluation", "required": [ "subject", "context" ], "properties": { "context": { "$ref": "#/components/schemas/SimulateContext", "description": "Context to test (resource_type, action, etc.)" }, "policy_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Optional: Only test a specific policy by ID" }, "subject": { "$ref": "#/components/schemas/SimulateSubject", "description": "Subject info to test (roles, user_id, etc.)" } } }, "SimulatePolicyResponse": { "type": "object", "description": "Response from policy simulation", "required": [ "rbac_enabled", "allowed", "system_policies_evaluated", "org_policies_evaluated" ], "properties": { "allowed": { "type": "boolean", "description": "Whether the request would be allowed" }, "matched_policy": { "type": [ "string", "null" ], "description": "Which policy determined the decision (if any)" }, "matched_policy_source": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PolicySource", "description": "Source of the matched policy (system or organization)" } ] }, "org_policies_evaluated": { "type": "array", "items": { "$ref": "#/components/schemas/PolicyEvaluationResult" }, "description": "Organization policies evaluated (from database, in priority order)" }, "rbac_enabled": { "type": "boolean", "description": "Whether RBAC is enabled (if false, all requests are allowed)" }, "reason": { "type": [ "string", "null" ], "description": "Reason for the decision" }, "system_policies_evaluated": { "type": "array", "items": { "$ref": "#/components/schemas/PolicyEvaluationResult" }, "description": "System policies evaluated (from config file, in priority order)" } } }, "SimulateRequestContext": { "type": "object", "description": "Request context for policy simulation (matches RequestContext but all fields optional)", "properties": { "character_count": { "type": [ "integer", "null" ], "format": "int64", "description": "Character count for TTS", "minimum": 0 }, "has_file_search": { "type": [ "boolean", "null" ], "description": "Whether the request includes file_search tool" }, "has_images": { "type": [ "boolean", "null" ], "description": "Whether the request contains image content" }, "has_tools": { "type": [ "boolean", "null" ], "description": "Whether the request includes tools/functions" }, "image_count": { "type": [ "integer", "null" ], "format": "int32", "description": "Number of images to generate", "minimum": 0 }, "image_quality": { "type": [ "string", "null" ], "description": "Image quality level" }, "image_size": { "type": [ "string", "null" ], "description": "Image size" }, "language": { "type": [ "string", "null" ], "description": "Language code for transcription" }, "max_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum tokens requested", "minimum": 0 }, "messages_count": { "type": [ "integer", "null" ], "format": "int64", "description": "Number of messages in the conversation", "minimum": 0 }, "reasoning_effort": { "type": [ "string", "null" ], "description": "Reasoning/thinking effort level" }, "response_format": { "type": [ "string", "null" ], "description": "Response format type" }, "stream": { "type": [ "boolean", "null" ], "description": "Whether streaming is requested" }, "temperature": { "type": [ "number", "null" ], "format": "double", "description": "Sampling temperature" }, "voice": { "type": [ "string", "null" ], "description": "Voice name for TTS" } } }, "SimulateSubject": { "type": "object", "description": "Subject information for policy simulation", "properties": { "email": { "type": [ "string", "null" ], "description": "Email address" }, "external_id": { "type": [ "string", "null" ], "description": "External ID from IdP" }, "org_ids": { "type": "array", "items": { "type": "string" }, "description": "Organization IDs the user belongs to" }, "project_ids": { "type": "array", "items": { "type": "string" }, "description": "Project IDs the user belongs to" }, "roles": { "type": "array", "items": { "type": "string" }, "description": "User's roles" }, "service_account_id": { "type": [ "string", "null" ], "description": "Service account ID (if simulating service account auth)" }, "team_ids": { "type": "array", "items": { "type": "string" }, "description": "Team IDs the user belongs to" }, "user_id": { "type": [ "string", "null" ], "description": "User ID (internal)" } } }, "Skill": { "type": "object", "description": "A packaged Agent Skill.", "required": [ "id", "owner_type", "owner_id", "name", "description", "total_bytes", "created_at", "updated_at" ], "properties": { "allowed_tools": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Tools the skill is allowed to use. Informational; the chat UI may\nuse this to pre-approve tools while the skill is active." }, "argument_hint": { "type": [ "string", "null" ], "description": "Hint shown during autocomplete to describe expected arguments." }, "created_at": { "type": "string", "format": "date-time" }, "description": { "type": "string", "description": "Human-readable description. Used by the model to decide when to\ninvoke the skill." }, "disable_model_invocation": { "type": [ "boolean", "null" ], "description": "If `true`, the model cannot auto-invoke this skill. `None` = unset\n(defaults to `false`)." }, "files": { "type": "array", "items": { "$ref": "#/components/schemas/SkillFile" }, "description": "Full file contents. Populated by get-by-id endpoints." }, "files_manifest": { "type": "array", "items": { "$ref": "#/components/schemas/SkillFileManifest" }, "description": "File summary (no contents). Populated by list endpoints." }, "frontmatter_extra": { "type": [ "object", "null" ], "description": "Unknown / forward-compat frontmatter keys preserved verbatim.", "additionalProperties": {}, "propertyNames": { "type": "string" } }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string", "description": "Skill name (unique per owner). See [`validate_skill_name`]." }, "owner_id": { "type": "string", "format": "uuid" }, "owner_type": { "$ref": "#/components/schemas/SkillOwnerType" }, "source_ref": { "type": [ "string", "null" ], "description": "Git ref if imported." }, "source_url": { "type": [ "string", "null" ], "description": "Origin URL if imported (e.g. a GitHub tree URL)." }, "total_bytes": { "type": "integer", "format": "int64", "description": "Cached total size across all files (bytes)." }, "updated_at": { "type": "string", "format": "date-time" }, "user_invocable": { "type": [ "boolean", "null" ], "description": "If `false`, the skill is hidden from the user-visible slash-command\nlist. `None` = unset (defaults to `true`)." } } }, "SkillFile": { "type": "object", "description": "A file bundled with a skill. Returned in full detail by get-by-id; list\nendpoints populate [`SkillFileManifest`] instead.", "required": [ "path", "content", "byte_size", "content_type", "created_at", "updated_at" ], "properties": { "byte_size": { "type": "integer", "format": "int64", "description": "Byte length of `content`." }, "content": { "type": "string", "description": "File contents. Text-only in v1 (binary assets unsupported)." }, "content_type": { "type": "string", "description": "MIME type, e.g. \"text/markdown\"." }, "created_at": { "type": "string", "format": "date-time" }, "path": { "type": "string", "description": "Relative path inside the skill, e.g. \"SKILL.md\" or \"scripts/extract.py\"." }, "updated_at": { "type": "string", "format": "date-time" } } }, "SkillFileInput": { "type": "object", "description": "A single file in a create/update request.", "required": [ "path", "content" ], "properties": { "content": { "type": "string" }, "content_type": { "type": [ "string", "null" ], "description": "Optional MIME type. If omitted, the service sniffs it from the path\nextension." }, "path": { "type": "string" } } }, "SkillFileManifest": { "type": "object", "description": "Lightweight file entry returned by list endpoints — contents omitted.", "required": [ "path", "byte_size", "content_type" ], "properties": { "byte_size": { "type": "integer", "format": "int64" }, "content_type": { "type": "string" }, "path": { "type": "string" } } }, "SkillListResponse": { "type": "object", "description": "Paginated list of skills.", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Skill" }, "description": "List of skills (file contents omitted; see `files_manifest` on each)." }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata." } } }, "SkillOwner": { "oneOf": [ { "type": "object", "required": [ "organization_id", "type" ], "properties": { "organization_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "organization" ] } } }, { "type": "object", "required": [ "team_id", "type" ], "properties": { "team_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "team" ] } } }, { "type": "object", "required": [ "project_id", "type" ], "properties": { "project_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "project" ] } } }, { "type": "object", "required": [ "user_id", "type" ], "properties": { "type": { "type": "string", "enum": [ "user" ] }, "user_id": { "type": "string", "format": "uuid" } } } ], "description": "Owner specification for creating a skill." }, "SkillOwnerType": { "type": "string", "description": "Owner type for skills (organization, team, project, or user).", "enum": [ "organization", "team", "project", "user" ] }, "SortOrder": { "type": "string", "description": "Sort order for list queries.\n\nOpenAI-compatible sort order parameter for paginated list endpoints.", "enum": [ "asc", "desc" ] }, "SovereigntyMetadata": { "type": "object", "description": "Sovereignty and compliance metadata for providers and models.\n\nWhen set at the provider level, these values apply to all models\nfrom that provider. Per-model overrides take precedence.", "properties": { "certifications": { "type": "array", "items": { "type": "string" }, "description": "Compliance certifications and regulatory frameworks.\nWell-known values: \"gdpr\", \"hipaa\", \"soc2\", \"soc2-type2\", \"iso27001\",\n\"fedramp\", \"fedramp-high\", \"pci-dss\", \"c5\", \"ismap\", \"hipaa-baa\", \"ccpa\", \"dpa\"" }, "custom": { "type": "object", "description": "Custom key-value metadata. Keys should match a defined custom field.", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "data_retention": { "type": [ "string", "null" ], "description": "Provider's data retention policy for request/response data.\nWell-known values: \"none\", \"30d\", \"90d\", \"1y\", \"indefinite\"" }, "hq_country": { "type": [ "string", "null" ], "description": "ISO 3166-1 alpha-2 country code of the provider's headquarters." }, "inference_countries": { "type": "array", "items": { "type": "string" }, "description": "ISO 3166-1 alpha-2 country codes where model inference runs." }, "license": { "type": [ "string", "null" ], "description": "Model license identifier.\nWell-known values: \"proprietary\", \"apache-2.0\", \"mit\", \"llama-3.1\",\n\"gemma\", \"mistral\", \"cc-by-4.0\", \"cc-by-nc-4.0\"" }, "notes": { "type": [ "string", "null" ], "description": "Free-form notes for additional context." }, "on_prem": { "type": [ "boolean", "null" ], "description": "Whether this provider/model runs on infrastructure operated by the org." }, "trains_on_data": { "type": [ "boolean", "null" ], "description": "Whether the provider trains on customer data.\nNone = unknown, true = yes, false = no (or opt-out available)." } } }, "SovereigntyRequirements": { "type": "object", "description": "Sovereignty requirements for API key restrictions.\n\nWhen set on an API key, only models whose resolved sovereignty metadata\nsatisfies all specified requirements can be used.", "properties": { "allowed_inference_countries": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Only allow models with inference in these countries." }, "allowed_licenses": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Only allow models with these licenses." }, "blocked_hq_countries": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Exclude models from providers headquartered in these countries." }, "require_on_prem": { "type": [ "boolean", "null" ], "description": "Only allow on-prem providers (sovereignty.on_prem == true)." }, "require_open_weights": { "type": [ "boolean", "null" ], "description": "Only allow open-weight models (open_weights == true)." }, "required_certifications": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Provider must have ALL of these certifications." } } }, "SpeechResponseFormat": { "type": "string", "description": "Audio output format for text-to-speech.", "enum": [ "mp3", "opus", "aac", "flac", "wav", "pcm" ] }, "SpeechStreamFormat": { "type": "string", "description": "Stream format for text-to-speech streaming.", "enum": [ "sse", "audio" ] }, "SsoConnection": { "type": "object", "description": "SSO connection info (read-only, from config)", "required": [ "name", "type", "jit_enabled", "sync_memberships_on_login" ], "properties": { "client_id": { "type": [ "string", "null" ], "description": "OIDC client ID (not the secret)" }, "default_org_role": { "type": [ "string", "null" ], "description": "Default org role for provisioned users" }, "default_team_id": { "type": [ "string", "null" ], "description": "Default team ID for provisioned users (if configured)" }, "default_team_role": { "type": [ "string", "null" ], "description": "Default team role for provisioned users" }, "groups_claim": { "type": [ "string", "null" ], "description": "Claim used for groups (if configured)" }, "identity_claim": { "type": [ "string", "null" ], "description": "Claim used for user identity" }, "issuer": { "type": [ "string", "null" ], "description": "OIDC issuer URL" }, "jit_enabled": { "type": "boolean", "description": "Whether JIT provisioning is enabled" }, "name": { "type": "string", "description": "Connection name (currently always \"default\")" }, "organization_id": { "type": [ "string", "null" ], "description": "Organization ID users are provisioned into (if JIT is enabled)" }, "scopes": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Configured scopes" }, "sync_memberships_on_login": { "type": "boolean", "description": "Whether to sync memberships on login" }, "type": { "type": "string", "description": "Type of SSO connection" } } }, "SsoConnectionInfo": { "type": "object", "description": "SSO connection information (from config).", "required": [ "name", "type", "jit_enabled" ], "properties": { "groups_claim": { "type": [ "string", "null" ], "description": "Claim used for groups (if configured)" }, "issuer": { "type": [ "string", "null" ], "description": "OIDC issuer URL (if OIDC)" }, "jit_enabled": { "type": "boolean", "description": "Whether JIT provisioning is enabled" }, "name": { "type": "string", "description": "Connection name" }, "type": { "type": "string", "description": "Connection type (oidc, proxy_auth)" } } }, "SsoConnectionsResponse": { "type": "object", "description": "Response containing all configured SSO connections", "required": [ "data" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/SsoConnection" }, "description": "List of SSO connections (currently max 1)" } } }, "SsoEnforcementMode": { "type": "string", "description": "SSO enforcement mode.", "enum": [ "optional", "required", "test" ] }, "SsoGroupMapping": { "type": "object", "description": "SSO Group Mapping - maps an IdP group to a Hadrian team and/or role.\n\nWhen a user logs in via SSO, their IdP groups are looked up in this table\nto determine which teams they should be added to and with what role.\n\nMultiple mappings per IdP group are allowed, enabling a single IdP group\nto grant membership to multiple Hadrian teams.", "required": [ "id", "sso_connection_name", "idp_group", "org_id", "priority", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time", "description": "When this mapping was created" }, "id": { "type": "string", "format": "uuid", "description": "Unique identifier for this mapping" }, "idp_group": { "type": "string", "description": "The IdP group name exactly as it appears in the groups claim" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization this mapping belongs to (mappings are org-scoped)" }, "priority": { "type": "integer", "format": "int32", "description": "Priority for role precedence (higher = wins when multiple mappings target same team)" }, "role": { "type": [ "string", "null" ], "description": "Role to assign (within the team if team_id is set, otherwise org-level role)" }, "sso_connection_name": { "type": "string", "description": "Which SSO connection this mapping applies to (from config, defaults to 'default')" }, "team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Team to add users to when they have this IdP group (optional)" }, "updated_at": { "type": "string", "format": "date-time", "description": "When this mapping was last updated" } } }, "SsoGroupMappingListResponse": { "type": "object", "description": "Paginated list of SSO group mappings", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/SsoGroupMapping" }, "description": "List of SSO group mappings" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "SsoProviderType": { "type": "string", "description": "SSO provider type.", "enum": [ "oidc", "saml" ] }, "StaleAccessQuery": { "type": "object", "description": "Query parameters for stale access detection endpoint", "properties": { "format": { "$ref": "#/components/schemas/ExportFormat", "description": "Export format (json or csv)" }, "inactive_days": { "type": [ "integer", "null" ], "format": "int64", "description": "Number of days of inactivity to consider access stale (default: 90)" }, "limit": { "type": [ "integer", "null" ], "format": "int64", "description": "Maximum number of results to return (default: 100, max: 1000)" }, "org_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Filter by organization ID" } } }, "StaleAccessResponse": { "type": "object", "description": "Response for stale access detection", "required": [ "generated_at", "inactive_days_threshold", "cutoff_date", "stale_users", "stale_api_keys", "never_active_users", "summary" ], "properties": { "cutoff_date": { "type": "string", "format": "date-time", "description": "Cutoff date (activity before this date is considered stale)" }, "generated_at": { "type": "string", "format": "date-time", "description": "When this report was generated" }, "inactive_days_threshold": { "type": "integer", "format": "int64", "description": "Number of days used as the inactivity threshold" }, "never_active_users": { "type": "array", "items": { "$ref": "#/components/schemas/NeverActiveUserEntry" }, "description": "Users with access but zero recorded activity" }, "stale_api_keys": { "type": "array", "items": { "$ref": "#/components/schemas/StaleApiKeyEntry" }, "description": "API keys with no recent usage" }, "stale_users": { "type": "array", "items": { "$ref": "#/components/schemas/StaleUserEntry" }, "description": "Users with stale access (no recent activity)" }, "summary": { "$ref": "#/components/schemas/StaleAccessSummary", "description": "Summary statistics" } } }, "StaleAccessSummary": { "type": "object", "description": "Summary statistics for stale access detection", "required": [ "total_users_scanned", "stale_users_count", "never_active_users_count", "total_api_keys_scanned", "stale_api_keys_count", "never_used_api_keys_count" ], "properties": { "never_active_users_count": { "type": "integer", "format": "int64", "description": "Number of users who have never been active" }, "never_used_api_keys_count": { "type": "integer", "format": "int64", "description": "Number of API keys never used" }, "stale_api_keys_count": { "type": "integer", "format": "int64", "description": "Number of stale API keys" }, "stale_users_count": { "type": "integer", "format": "int64", "description": "Number of users with stale access" }, "total_api_keys_scanned": { "type": "integer", "format": "int64", "description": "Total active API keys scanned" }, "total_users_scanned": { "type": "integer", "format": "int64", "description": "Total users scanned" } } }, "StaleApiKeyEntry": { "type": "object", "description": "An API key identified as stale (not used recently)", "required": [ "key_id", "name", "key_prefix", "owner_type", "owner_id", "created_at", "days_inactive", "never_used" ], "properties": { "created_at": { "type": "string", "format": "date-time", "description": "When the key was created" }, "days_inactive": { "type": "integer", "format": "int64", "description": "Days since last use (or since creation if never used)" }, "key_id": { "type": "string", "format": "uuid", "description": "API key ID" }, "key_prefix": { "type": "string", "description": "Key prefix for identification" }, "last_used_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the key was last used (if ever)" }, "name": { "type": "string", "description": "API key name" }, "never_used": { "type": "boolean", "description": "Whether the key has ever been used" }, "owner_id": { "type": "string", "format": "uuid", "description": "Owner ID" }, "owner_type": { "type": "string", "description": "Owner type (organization, project, or user)" } } }, "StaleUserEntry": { "type": "object", "description": "A user identified as having stale access", "required": [ "user_id", "external_id", "created_at", "days_inactive", "org_count", "project_count", "active_api_keys" ], "properties": { "active_api_keys": { "type": "integer", "format": "int64", "description": "Number of active API keys" }, "created_at": { "type": "string", "format": "date-time", "description": "When the user was created" }, "days_inactive": { "type": "integer", "format": "int64", "description": "Days since last activity" }, "email": { "type": [ "string", "null" ], "description": "User's email (if available)" }, "external_id": { "type": "string", "description": "User's external identifier" }, "last_activity_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last activity timestamp (before the cutoff)" }, "name": { "type": [ "string", "null" ], "description": "User's name (if available)" }, "org_count": { "type": "integer", "format": "int64", "description": "Number of organization memberships" }, "project_count": { "type": "integer", "format": "int64", "description": "Number of project memberships" }, "user_id": { "type": "string", "format": "uuid", "description": "User ID" } } }, "StaticChunkingConfig": { "type": "object", "description": "Static chunking configuration (OpenAI-compatible)", "properties": { "chunk_overlap_tokens": { "type": "integer", "format": "int32" }, "max_chunk_size_tokens": { "type": "integer", "format": "int32" } } }, "StatsGranularity": { "type": "string", "description": "Granularity for historical stats queries.", "enum": [ "hour", "day" ] }, "Stop": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" } } ], "description": "Stop sequence(s) for generation" }, "StreamOptions": { "type": "object", "description": "Stream options", "required": [ "include_usage" ], "properties": { "include_usage": { "type": "boolean" } } }, "SubsystemStatus": { "type": "object", "description": "Status of individual subsystems.", "properties": { "cache": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ComponentStatus", "description": "Cache connection status" } ] }, "database": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ComponentStatus", "description": "Database connection status" } ] }, "secrets": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ComponentStatus", "description": "Secrets manager status" } ] } } }, "Team": { "type": "object", "required": [ "id", "org_id", "slug", "name", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "org_id": { "type": "string", "format": "uuid" }, "slug": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "TeamListResponse": { "type": "object", "description": "Paginated list of teams", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Team" }, "description": "List of teams" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "TeamMember": { "type": "object", "description": "Member of a team (user with role)", "required": [ "user_id", "external_id", "role", "joined_at" ], "properties": { "email": { "type": [ "string", "null" ], "description": "User's email (if available)" }, "external_id": { "type": "string", "description": "User's external ID" }, "joined_at": { "type": "string", "format": "date-time", "description": "When the user joined the team" }, "name": { "type": [ "string", "null" ], "description": "User's name (if available)" }, "role": { "type": "string", "description": "User's role in the team" }, "user_id": { "type": "string", "format": "uuid", "description": "User ID" } } }, "TeamMemberListResponse": { "type": "object", "description": "Paginated list of team members", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/TeamMember" }, "description": "List of team members" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "TeamMembership": { "type": "object", "description": "Team membership for a user", "required": [ "team_id", "team_slug", "team_name", "org_id", "role", "source", "joined_at" ], "properties": { "joined_at": { "type": "string", "format": "date-time", "description": "When the user joined the team" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization ID the team belongs to" }, "role": { "type": "string", "description": "User's role in the team" }, "source": { "$ref": "#/components/schemas/MembershipSource", "description": "Source of this membership (manual, jit, scim)" }, "team_id": { "type": "string", "format": "uuid", "description": "Team ID" }, "team_name": { "type": "string", "description": "Team name" }, "team_slug": { "type": "string", "description": "Team slug" } } }, "TeamMembershipInfo": { "type": "object", "description": "Team membership information.", "required": [ "team_id", "team_slug", "team_name", "org_slug", "role", "joined_at" ], "properties": { "joined_at": { "type": "string", "format": "date-time", "description": "When the membership was created" }, "org_slug": { "type": "string", "description": "Organization the team belongs to" }, "role": { "type": "string", "description": "User's role in this team" }, "team_id": { "type": "string", "format": "uuid", "description": "Team ID" }, "team_name": { "type": "string", "description": "Team name" }, "team_slug": { "type": "string", "description": "Team slug" } } }, "TeamSpendResponse": { "type": "object", "description": "Usage breakdown by team", "required": [ "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64" }, "character_count": { "type": "integer", "format": "int64" }, "image_count": { "type": "integer", "format": "int64" }, "input_tokens": { "type": "integer", "format": "int64" }, "output_tokens": { "type": "integer", "format": "int64" }, "request_count": { "type": "integer", "format": "int64" }, "team_id": { "type": [ "string", "null" ] }, "team_name": { "type": [ "string", "null" ] }, "total_cost": { "type": "number", "format": "double" }, "total_tokens": { "type": "integer", "format": "int64" } } }, "Template": { "type": "object", "description": "A reusable system template", "required": [ "id", "owner_type", "owner_id", "name", "content", "created_at", "updated_at" ], "properties": { "content": { "type": "string", "description": "The actual template content (system message template)" }, "created_at": { "type": "string", "format": "date-time" }, "description": { "type": [ "string", "null" ], "description": "Optional description of what this template does" }, "id": { "type": "string", "format": "uuid" }, "metadata": { "type": [ "object", "null" ], "description": "Optional metadata (e.g., recommended temperature, max_tokens, tags)", "additionalProperties": {}, "propertyNames": { "type": "string" } }, "name": { "type": "string", "description": "Name of the template" }, "owner_id": { "type": "string", "format": "uuid" }, "owner_type": { "$ref": "#/components/schemas/TemplateOwnerType" }, "updated_at": { "type": "string", "format": "date-time" } } }, "TemplateListResponse": { "type": "object", "description": "Paginated list of templates", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Template" }, "description": "List of templates" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "TemplateOwner": { "oneOf": [ { "type": "object", "required": [ "organization_id", "type" ], "properties": { "organization_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "organization" ] } } }, { "type": "object", "required": [ "team_id", "type" ], "properties": { "team_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "team" ] } } }, { "type": "object", "required": [ "project_id", "type" ], "properties": { "project_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "project" ] } } }, { "type": "object", "required": [ "user_id", "type" ], "properties": { "type": { "type": "string", "enum": [ "user" ] }, "user_id": { "type": "string", "format": "uuid" } } } ], "description": "Owner specification for creating a template" }, "TemplateOwnerType": { "type": "string", "description": "Owner type for templates (organization, team, project, or user)", "enum": [ "organization", "team", "project", "user" ] }, "TestMappingRequest": { "type": "object", "description": "Request to test SSO group mapping resolution", "required": [ "idp_groups" ], "properties": { "default_role": { "type": "string", "description": "Default role to use for mappings without a role (defaults to 'member')" }, "idp_groups": { "type": "array", "items": { "type": "string" }, "description": "List of IdP group names to test" }, "sso_connection_name": { "type": "string", "description": "SSO connection name (defaults to 'default')" } } }, "TestMappingResponse": { "type": "object", "description": "Response from testing SSO group mapping resolution", "required": [ "resolved", "unmapped_groups" ], "properties": { "resolved": { "type": "array", "items": { "$ref": "#/components/schemas/TestMappingResult" }, "description": "Groups that matched mappings and their resolved teams/roles" }, "unmapped_groups": { "type": "array", "items": { "type": "string" }, "description": "Groups that did not match any mapping" } } }, "TestMappingResult": { "type": "object", "description": "A resolved team membership from the test", "required": [ "idp_group", "team_id", "team_name", "role" ], "properties": { "idp_group": { "type": "string", "description": "The IdP group that matched" }, "role": { "type": "string", "description": "Role that would be assigned" }, "team_id": { "type": "string", "format": "uuid", "description": "Team ID the user would be added to" }, "team_name": { "type": "string", "description": "Team name (for display)" } } }, "TimeBucketStats": { "type": "object", "description": "Historical statistics for a time bucket.", "required": [ "bucket_start", "bucket_duration_secs", "request_count", "error_count", "total_tokens", "total_cost_microcents" ], "properties": { "avg_latency_ms": { "type": [ "number", "null" ], "format": "double", "description": "Average latency" }, "bucket_duration_secs": { "type": "integer", "format": "int64", "description": "Duration of the bucket in seconds" }, "bucket_start": { "type": "string", "format": "date-time", "description": "Start of the time bucket" }, "error_count": { "type": "integer", "format": "int64", "description": "Error count in this bucket" }, "p50_latency_ms": { "type": [ "number", "null" ], "format": "double", "description": "50th percentile latency" }, "p95_latency_ms": { "type": [ "number", "null" ], "format": "double", "description": "95th percentile latency" }, "p99_latency_ms": { "type": [ "number", "null" ], "format": "double", "description": "99th percentile latency" }, "request_count": { "type": "integer", "format": "int64", "description": "Request count in this bucket" }, "total_cost_microcents": { "type": "integer", "format": "int64", "description": "Total cost in this bucket" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens in this bucket" } } }, "TimeSeriesForecastResponse": { "type": "object", "description": "Time series forecast with prediction intervals", "required": [ "dates", "point_forecasts", "lower_bounds", "upper_bounds", "confidence_level", "used_seasonal_decomposition" ], "properties": { "confidence_level": { "type": "number", "format": "double", "description": "Confidence level for prediction intervals (e.g., 0.95 for 95%)" }, "dates": { "type": "array", "items": { "type": "string" }, "description": "Dates for each forecast point (YYYY-MM-DD)" }, "lower_bounds": { "type": "array", "items": { "type": "number", "format": "double" }, "description": "Lower bound of prediction interval (dollars)" }, "point_forecasts": { "type": "array", "items": { "type": "number", "format": "double" }, "description": "Point forecasts (daily spend in dollars)" }, "upper_bounds": { "type": "array", "items": { "type": "number", "format": "double" }, "description": "Upper bound of prediction interval (dollars)" }, "used_seasonal_decomposition": { "type": "boolean", "description": "Whether MSTL decomposition was used (false = simple ETS)" } } }, "TimestampGranularity": { "type": "string", "description": "Timestamp granularity options for transcription.", "enum": [ "word", "segment" ] }, "ToolCall": { "type": "object", "description": "Tool call made by the model", "required": [ "id", "type", "function" ], "properties": { "function": { "$ref": "#/components/schemas/ToolCallFunction" }, "id": { "type": "string" }, "type": { "$ref": "#/components/schemas/ToolType" } } }, "ToolCallFunction": { "type": "object", "description": "Tool call function details", "required": [ "name", "arguments" ], "properties": { "arguments": { "type": "string", "description": "JSON-encoded arguments" }, "name": { "type": "string" } } }, "ToolChoice": { "oneOf": [ { "$ref": "#/components/schemas/ToolChoiceDefaults" }, { "$ref": "#/components/schemas/NamedToolChoice" } ], "description": "Tool choice configuration" }, "ToolChoiceDefaults": { "type": "string", "description": "Default tool choice options", "enum": [ "none", "auto", "required" ] }, "ToolDefinition": { "type": "object", "description": "Tool definition", "required": [ "type", "function" ], "properties": { "cache_control": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CacheControl", "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" } ] }, "function": { "$ref": "#/components/schemas/ToolDefinitionFunction" }, "type": { "$ref": "#/components/schemas/ToolType" } } }, "ToolDefinitionFunction": { "type": "object", "description": "Tool function definition", "required": [ "name" ], "properties": { "description": { "type": [ "string", "null" ] }, "name": { "type": "string" }, "parameters": { "type": "object", "description": "JSON Schema for function parameters" }, "strict": { "type": [ "boolean", "null" ] } } }, "ToolSearchExecution": { "type": "string", "description": "Whether a tool search ran on the server (Hadrian / OpenAI) or was\ndelegated to the client (BYOT). Hadrian only emits `Server`. Mirrors\nOpenAI's `ToolSearchExecutionType`.", "enum": [ "server", "client" ] }, "ToolSearchRankerKind": { "type": "string", "description": "Ranking strategy for Hadrian-side tool search over a deferred MCP\ncatalog. `Hybrid` fuses semantic + lexical relevance (RRF); `Semantic`\nis embedding cosine only; `Lexical` is token/substring scoring with no\nembedding dependency.", "enum": [ "hybrid", "semantic", "lexical" ] }, "ToolSearchTool": { "type": "object", "description": "`tool_search` tool — OpenAI's `ToolSearchToolParam`. Configures\ndiscovery of deferred tools (`defer_loading: true`). Under\n`hadrian_hosted` a caller need not supply this: Hadrian synthesizes\nits own search tool whenever a deferred MCP server is present. A\ncaller may still include the entry to set the Hadrian-extension\n`ranker`; Hadrian reads that override and does not forward the entry\nto the model.", "required": [ "type" ], "properties": { "description": { "type": [ "string", "null" ], "description": "Description shown to the model for a client-executed search tool." }, "execution": { "type": [ "string", "null" ], "description": "Whether the search executes server-side (hosted) or client-side\n(BYOT). Hadrian only supports server-side execution." }, "parameters": { "type": [ "object", "null" ], "description": "Parameter schema for a client-executed search tool. Opaque." }, "ranker": { "type": [ "string", "null" ], "description": "**Hadrian Extension:** per-request override of the ranking\nstrategy for Hadrian-side tool search. Takes precedence over the\n`[features.mcp.tool_search].ranker` deployment default. Requesting\n`semantic` on a deployment without an embedding provider returns\nHTTP 400 (`tool_search_ranker_unavailable`)." }, "type": { "$ref": "#/components/schemas/ToolSearchToolType" } } }, "ToolSearchToolType": { "type": "string", "enum": [ "tool_search" ] }, "ToolType": { "type": "string", "description": "Tool type", "enum": [ "function" ] }, "TranscriptionChunkingStrategy": { "type": "string", "description": "Chunking strategy for transcription.", "enum": [ "auto" ] }, "TranscriptionDiarizedResponse": { "type": "object", "description": "Diarized transcription response with speaker labels.", "required": [ "task", "duration", "text", "segments" ], "properties": { "duration": { "type": "number", "format": "float", "description": "The duration of the input audio in seconds." }, "segments": { "type": "array", "items": { "$ref": "#/components/schemas/TranscriptionDiarizedSegment" }, "description": "Segments with speaker annotations." }, "task": { "type": "string", "description": "The task type (always \"transcribe\")." }, "text": { "type": "string", "description": "The concatenated transcript text." }, "usage": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/TranscriptionUsage", "description": "Usage statistics." } ] } } }, "TranscriptionDiarizedSegment": { "type": "object", "description": "A diarized segment with speaker information.", "required": [ "type", "id", "start", "end", "text" ], "properties": { "end": { "type": "number", "format": "float", "description": "End time of the segment in seconds." }, "id": { "type": "string", "description": "Segment identifier." }, "speaker": { "type": [ "string", "null" ], "description": "The detected speaker label for this segment." }, "start": { "type": "number", "format": "float", "description": "Start time of the segment in seconds." }, "text": { "type": "string", "description": "Text content of the segment." }, "type": { "type": "string", "description": "The type of segment." } } }, "TranscriptionInclude": { "type": "string", "description": "Additional information to include in transcription response.", "enum": [ "logprobs" ] }, "TranscriptionInputTokenDetails": { "type": "object", "description": "Token usage details for transcription input.", "properties": { "audio_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Number of audio tokens in input." }, "text_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Number of text tokens in input." } } }, "TranscriptionLogprob": { "type": "object", "description": "Log probability information for a token.", "required": [ "token", "logprob" ], "properties": { "bytes": { "type": [ "array", "null" ], "items": { "type": "integer", "format": "int32" }, "description": "The bytes of the token." }, "logprob": { "type": "number", "format": "float", "description": "The log probability of the token." }, "token": { "type": "string", "description": "The token in the transcription." } } }, "TranscriptionResponse": { "type": "object", "description": "Basic transcription response (JSON format).", "required": [ "text" ], "properties": { "logprobs": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/TranscriptionLogprob" }, "description": "Log probabilities of tokens (if requested)." }, "text": { "type": "string", "description": "The transcribed text." }, "usage": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/TranscriptionUsage", "description": "Usage statistics." } ] } } }, "TranscriptionSegment": { "type": "object", "description": "A segment of transcribed text with detailed information.", "required": [ "id", "start", "end", "text" ], "properties": { "avg_logprob": { "type": [ "number", "null" ], "format": "float", "description": "Average logprob of the segment." }, "compression_ratio": { "type": [ "number", "null" ], "format": "float", "description": "Compression ratio of the segment." }, "end": { "type": "number", "format": "float", "description": "End time of the segment in seconds." }, "id": { "type": "integer", "format": "int32", "description": "Unique identifier of the segment." }, "no_speech_prob": { "type": [ "number", "null" ], "format": "float", "description": "Probability of no speech in the segment." }, "seek": { "type": [ "integer", "null" ], "format": "int32", "description": "Seek offset of the segment." }, "start": { "type": "number", "format": "float", "description": "Start time of the segment in seconds." }, "temperature": { "type": [ "number", "null" ], "format": "float", "description": "Temperature parameter used for generating the segment." }, "text": { "type": "string", "description": "Text content of the segment." }, "tokens": { "type": [ "array", "null" ], "items": { "type": "integer", "format": "int32" }, "description": "Array of token IDs for the text content." } } }, "TranscriptionUsage": { "oneOf": [ { "$ref": "#/components/schemas/TranscriptionUsageTokens" }, { "$ref": "#/components/schemas/TranscriptionUsageDuration" } ], "description": "Usage statistics for transcription (can be token-based or duration-based)." }, "TranscriptionUsageDuration": { "type": "object", "description": "Duration-based usage statistics for transcription.", "required": [ "type", "seconds" ], "properties": { "seconds": { "type": "integer", "format": "int64", "description": "Duration in seconds." }, "type": { "type": "string", "description": "The type of usage (always \"duration\")." } } }, "TranscriptionUsageTokens": { "type": "object", "description": "Token-based usage statistics for transcription.", "required": [ "type", "total_tokens", "input_tokens" ], "properties": { "input_token_details": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/TranscriptionInputTokenDetails", "description": "Breakdown of input token types." } ] }, "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens used." }, "output_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Output tokens used." }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens used." }, "type": { "type": "string", "description": "The type of usage (always \"tokens\")." } } }, "TranscriptionVerboseResponse": { "type": "object", "description": "Verbose transcription response with timestamps and segments.", "required": [ "language", "duration", "text" ], "properties": { "duration": { "type": "number", "format": "float", "description": "The duration of the input audio in seconds." }, "language": { "type": "string", "description": "The language of the input audio." }, "segments": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/TranscriptionSegment" }, "description": "Segments of the transcribed text." }, "task": { "type": [ "string", "null" ], "description": "The task type (always \"transcribe\")." }, "text": { "type": "string", "description": "The transcribed text." }, "usage": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/TranscriptionUsage", "description": "Usage statistics." } ] }, "words": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/TranscriptionWord" }, "description": "Extracted words and their timestamps." } } }, "TranscriptionWord": { "type": "object", "description": "A word with timestamp information.", "required": [ "word" ], "properties": { "end": { "type": [ "number", "null" ], "format": "float", "description": "End time of the word in seconds." }, "start": { "type": [ "number", "null" ], "format": "float", "description": "Start time of the word in seconds." }, "word": { "type": "string", "description": "The text content of the word." } } }, "TranslationResponse": { "type": "object", "description": "Basic translation response (JSON format).", "required": [ "text" ], "properties": { "text": { "type": "string", "description": "The translated text." } } }, "TranslationVerboseResponse": { "type": "object", "description": "Verbose translation response with timestamps and segments.", "required": [ "language", "duration", "text" ], "properties": { "duration": { "type": "number", "format": "float", "description": "The duration of the input audio in seconds." }, "language": { "type": "string", "description": "The language of the output translation (always \"english\")." }, "segments": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/TranscriptionSegment" }, "description": "Segments of the translated text." }, "text": { "type": "string", "description": "The translated text." } } }, "UpdateConversation": { "type": "object", "description": "Request to update a conversation", "properties": { "messages": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/Message" }, "description": "Replace all messages" }, "models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "New models list" }, "owner": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ConversationOwner", "description": "New owner (to move conversation to a different project or user)" } ] }, "title": { "type": [ "string", "null" ], "description": "New title" } } }, "UpdateDynamicProvider": { "type": "object", "properties": { "api_key": { "type": [ "string", "null" ], "description": "Raw API key (stored in secrets manager if available, otherwise stored directly)" }, "base_url": { "type": [ "string", "null" ] }, "config": { "description": "Provider-specific configuration (e.g., region, credentials for Bedrock/Vertex)" }, "is_enabled": { "type": [ "boolean", "null" ] }, "models": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "List of supported model names" }, "sovereignty": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SovereigntyMetadata", "description": "Sovereignty and compliance metadata (set to null to clear)" } ] } } }, "UpdateModelPricing": { "type": "object", "description": "Request to update model pricing", "properties": { "cache_write_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M cache write tokens in microcents" }, "cached_input_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M cached input tokens in microcents" }, "input_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M input tokens in microcents" }, "output_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M output tokens in microcents" }, "per_1m_characters": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M characters in microcents (for TTS)" }, "per_image": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per image in microcents" }, "per_request": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per request in microcents" }, "per_second": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per second of audio in microcents (for transcription/translation)" }, "reasoning_per_1m_tokens": { "type": [ "integer", "null" ], "format": "int64", "description": "Cost per 1M reasoning tokens in microcents" }, "source": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PricingSource" } ] } } }, "UpdateOrgRbacPolicy": { "type": "object", "description": "Request to update an existing organization RBAC policy.\n\nAll fields are optional - only provided fields will be updated.\nEach update increments the policy version and creates a version history record.", "properties": { "action": { "type": [ "string", "null" ], "description": "Update the action pattern" }, "condition": { "type": [ "string", "null" ], "description": "Update the CEL condition" }, "description": { "type": [ "string", "null" ], "description": "Update the description (set to null to remove)" }, "effect": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/RbacPolicyEffect", "description": "Update the policy effect" } ] }, "enabled": { "type": [ "boolean", "null" ], "description": "Update the enabled state" }, "name": { "type": [ "string", "null" ], "description": "Update the policy name" }, "priority": { "type": [ "integer", "null" ], "format": "int32", "description": "Update the priority (valid range: -1000 to 1000)" }, "reason": { "type": [ "string", "null" ], "description": "Reason for the update (stored in version history)" }, "resource": { "type": [ "string", "null" ], "description": "Update the resource pattern" } } }, "UpdateOrgScimConfig": { "type": "object", "description": "Request to update an existing organization SCIM configuration.\n\nAll fields are optional - only provided fields will be updated.", "properties": { "create_users": { "type": [ "boolean", "null" ], "description": "Update create users flag" }, "deactivate_deletes_user": { "type": [ "boolean", "null" ], "description": "Update deactivate deletes user flag" }, "default_org_role": { "type": [ "string", "null" ], "description": "Update default org role" }, "default_team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Update default team (set to null to remove)" }, "default_team_role": { "type": [ "string", "null" ], "description": "Update default team role" }, "enabled": { "type": [ "boolean", "null" ], "description": "Update enabled flag" }, "revoke_api_keys_on_deactivate": { "type": [ "boolean", "null" ], "description": "Update revoke API keys on deactivate flag" }, "sync_display_name": { "type": [ "boolean", "null" ], "description": "Update sync display name flag" } } }, "UpdateOrgSsoConfig": { "type": "object", "description": "Request to update an existing organization SSO configuration.\n\nAll fields are optional - only provided fields will be updated.", "properties": { "allowed_email_domains": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Update allowed email domains" }, "client_id": { "type": [ "string", "null" ], "description": "Update OAuth2 client ID" }, "client_secret": { "type": [ "string", "null" ], "description": "Update OAuth2 client secret (will be stored in secret manager)" }, "create_users": { "type": [ "boolean", "null" ], "description": "Update create users flag" }, "default_org_role": { "type": [ "string", "null" ], "description": "Update default org role" }, "default_team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Update default team (set to null to remove)" }, "default_team_role": { "type": [ "string", "null" ], "description": "Update default team role" }, "discovery_url": { "type": [ "string", "null" ], "description": "Update discovery URL (set to null to use default)" }, "enabled": { "type": [ "boolean", "null" ], "description": "Update enabled flag" }, "enforcement_mode": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SsoEnforcementMode", "description": "Update enforcement mode" } ] }, "groups_claim": { "type": [ "string", "null" ], "description": "Update groups claim (set to null to remove)" }, "identity_claim": { "type": [ "string", "null" ], "description": "Update identity claim" }, "issuer": { "type": [ "string", "null" ], "description": "Update OIDC issuer URL" }, "org_claim": { "type": [ "string", "null" ], "description": "Update org claim (set to null to remove)" }, "provider_type": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/SsoProviderType", "description": "Update provider type" } ] }, "provisioning_enabled": { "type": [ "boolean", "null" ], "description": "Update provisioning enabled flag" }, "redirect_uri": { "type": [ "string", "null" ], "description": "Update redirect URI (set to null to use global default)" }, "saml_authn_context_class_ref": { "type": [ "string", "null" ], "description": "Update authentication context class (set to null to remove)" }, "saml_email_attribute": { "type": [ "string", "null" ], "description": "Update SAML email attribute (set to null to remove)" }, "saml_force_authn": { "type": [ "boolean", "null" ], "description": "Update force re-authentication flag" }, "saml_groups_attribute": { "type": [ "string", "null" ], "description": "Update SAML groups attribute (set to null to remove)" }, "saml_identity_attribute": { "type": [ "string", "null" ], "description": "Update SAML identity attribute (set to null to remove)" }, "saml_idp_certificate": { "type": [ "string", "null" ], "description": "Update IdP certificate (set to null to remove)" }, "saml_idp_entity_id": { "type": [ "string", "null" ], "description": "Update IdP entity identifier (set to null to remove)" }, "saml_idp_slo_url": { "type": [ "string", "null" ], "description": "Update IdP SLO URL (set to null to remove)" }, "saml_idp_sso_url": { "type": [ "string", "null" ], "description": "Update IdP SSO URL (set to null to remove)" }, "saml_metadata_url": { "type": [ "string", "null" ], "description": "Update IdP metadata URL (set to null to remove)" }, "saml_name_attribute": { "type": [ "string", "null" ], "description": "Update SAML name attribute (set to null to remove)" }, "saml_name_id_format": { "type": [ "string", "null" ], "description": "Update NameID format (set to null to remove)" }, "saml_sign_requests": { "type": [ "boolean", "null" ], "description": "Update sign requests flag" }, "saml_sp_certificate": { "type": [ "string", "null" ], "description": "Update SP certificate (set to null to remove)" }, "saml_sp_entity_id": { "type": [ "string", "null" ], "description": "Update SP entity ID (set to null to remove)" }, "saml_sp_private_key": { "type": [ "string", "null" ], "description": "Update SP private key (will be stored in secret manager)" }, "scopes": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "Update OAuth2 scopes" }, "sync_attributes_on_login": { "type": [ "boolean", "null" ], "description": "Update sync attributes on login flag" }, "sync_memberships_on_login": { "type": [ "boolean", "null" ], "description": "Update sync memberships on login flag" } } }, "UpdateOrganization": { "type": "object", "properties": { "name": { "type": [ "string", "null" ], "description": "New display name" } } }, "UpdateProject": { "type": "object", "properties": { "name": { "type": [ "string", "null" ], "description": "New display name" }, "team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Team to assign the project to (use null to remove team assignment)" } } }, "UpdateServiceAccount": { "type": "object", "description": "Request to update an existing service account", "properties": { "description": { "type": [ "string", "null" ], "description": "New description" }, "name": { "type": [ "string", "null" ], "description": "New display name" }, "roles": { "type": [ "array", "null" ], "items": { "type": "string" }, "description": "New roles (replaces existing roles)" } } }, "UpdateSkill": { "type": "object", "description": "Request to update a skill. Any field that is `Some(_)` replaces the\nstored value. When `files` is `Some(_)`, the entire file set is\nreplaced.", "properties": { "allowed_tools": { "type": [ "array", "null" ], "items": { "type": "string" } }, "argument_hint": { "type": [ "string", "null" ] }, "description": { "type": [ "string", "null" ] }, "disable_model_invocation": { "type": [ "boolean", "null" ] }, "files": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/SkillFileInput" } }, "frontmatter_extra": { "type": [ "object", "null" ], "additionalProperties": {}, "propertyNames": { "type": "string" } }, "name": { "type": [ "string", "null" ] }, "source_ref": { "type": [ "string", "null" ] }, "source_url": { "type": [ "string", "null" ] }, "user_invocable": { "type": [ "boolean", "null" ] } } }, "UpdateSsoGroupMapping": { "type": "object", "description": "Request to update an existing SSO group mapping.\n\nAll fields are optional - only provided fields will be updated.", "properties": { "idp_group": { "type": [ "string", "null" ], "description": "Update the IdP group name" }, "priority": { "type": [ "integer", "null" ], "format": "int32", "description": "Update the priority (higher = wins when multiple mappings target same team)" }, "role": { "type": [ "string", "null" ], "description": "Update the role (set to null to remove role assignment)" }, "team_id": { "type": [ "string", "null" ], "format": "uuid", "description": "Update the team assignment (set to null to remove team assignment)" } } }, "UpdateTeam": { "type": "object", "properties": { "name": { "type": [ "string", "null" ], "description": "New display name" } } }, "UpdateTeamMember": { "type": "object", "description": "Request to update a team member's role", "required": [ "role" ], "properties": { "role": { "type": "string", "description": "New role to assign" } } }, "UpdateTemplate": { "type": "object", "description": "Request to update a template", "properties": { "content": { "type": [ "string", "null" ], "description": "New content" }, "description": { "type": [ "string", "null" ], "description": "New description" }, "metadata": { "type": [ "object", "null" ], "description": "New metadata (replaces existing)", "additionalProperties": {}, "propertyNames": { "type": "string" } }, "name": { "type": [ "string", "null" ], "description": "New name (unique per owner)" } } }, "UpdateUser": { "type": "object", "properties": { "email": { "type": [ "string", "null" ] }, "name": { "type": [ "string", "null" ] } } }, "UpdateVectorStore": { "type": "object", "description": "Request to update a vector store (vector store).\n\n## Hadrian Extensions\n\nThe following field is a **Hadrian extension** not present in the standard OpenAI API:\n- `description`: Human-readable description", "properties": { "description": { "type": [ "string", "null" ], "description": "**Hadrian Extension:** New description" }, "expires_after": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ExpiresAfter", "description": "New expiration policy" } ] }, "metadata": { "type": [ "object", "null" ], "description": "New metadata (replaces existing, up to 16 key-value pairs, keys max 64 chars, string values max 512 chars)", "additionalProperties": {}, "propertyNames": { "type": "string" } }, "name": { "type": [ "string", "null" ], "description": "New name" } } }, "UsageLogExportFormat": { "type": "string", "description": "Export format for usage logs", "enum": [ "csv", "jsonl" ] }, "UsageLogListResponse": { "type": "object", "description": "Paginated list of usage log records", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/UsageLogResponse" } }, "pagination": { "$ref": "#/components/schemas/PaginationMeta" } } }, "UsageLogResponse": { "type": "object", "description": "Individual usage log entry response", "required": [ "id", "recorded_at", "request_id", "model", "provider", "input_tokens", "output_tokens", "cached_tokens", "reasoning_tokens", "cost", "streamed", "cancelled", "pricing_source" ], "properties": { "api_key_id": { "type": [ "string", "null" ], "format": "uuid" }, "audio_seconds": { "type": [ "integer", "null" ], "format": "int32" }, "cached_tokens": { "type": "integer", "format": "int32" }, "cancelled": { "type": "boolean" }, "character_count": { "type": [ "integer", "null" ], "format": "int32" }, "cost": { "type": "number", "format": "double", "description": "Cost in dollars" }, "finish_reason": { "type": [ "string", "null" ] }, "http_referer": { "type": [ "string", "null" ] }, "id": { "type": "string", "format": "uuid" }, "image_count": { "type": [ "integer", "null" ], "format": "int32" }, "input_tokens": { "type": "integer", "format": "int32" }, "latency_ms": { "type": [ "integer", "null" ], "format": "int32" }, "model": { "type": "string" }, "org_id": { "type": [ "string", "null" ], "format": "uuid" }, "output_tokens": { "type": "integer", "format": "int32" }, "pricing_source": { "type": "string" }, "project_id": { "type": [ "string", "null" ], "format": "uuid" }, "provider": { "type": "string" }, "provider_source": { "type": [ "string", "null" ] }, "reasoning_tokens": { "type": "integer", "format": "int32" }, "recorded_at": { "type": "string" }, "request_id": { "type": "string" }, "service_account_id": { "type": [ "string", "null" ], "format": "uuid" }, "status_code": { "type": [ "integer", "null" ], "format": "int32" }, "streamed": { "type": "boolean" }, "team_id": { "type": [ "string", "null" ], "format": "uuid" }, "user_id": { "type": [ "string", "null" ], "format": "uuid" } } }, "UsageQuery": { "type": "object", "description": "Query parameters for usage endpoints", "properties": { "end_date": { "type": [ "string", "null" ], "description": "End date (YYYY-MM-DD)" }, "start_date": { "type": [ "string", "null" ], "description": "Start date (YYYY-MM-DD)" } } }, "UsageSummaryResponse": { "type": "object", "description": "Usage summary response", "required": [ "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Audio duration in seconds" }, "character_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Character count (TTS input)" }, "first_request_at": { "type": [ "string", "null" ], "description": "First request timestamp (RFC3339)" }, "image_count": { "type": "integer", "format": "int64", "description": "**Hadrian Extension:** Number of images generated" }, "input_tokens": { "type": "integer", "format": "int64", "description": "Input tokens used" }, "last_request_at": { "type": [ "string", "null" ], "description": "Last request timestamp (RFC3339)" }, "output_tokens": { "type": "integer", "format": "int64", "description": "Output tokens used" }, "request_count": { "type": "integer", "format": "int64", "description": "Number of requests" }, "total_cost": { "type": "number", "format": "double", "description": "Total cost in dollars" }, "total_tokens": { "type": "integer", "format": "int64", "description": "Total tokens used" } } }, "User": { "type": "object", "required": [ "id", "external_id", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "email": { "type": [ "string", "null" ] }, "external_id": { "type": "string", "description": "External identifier (e.g., from SSO provider)" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": [ "string", "null" ] }, "updated_at": { "type": "string", "format": "date-time" } } }, "UserAccessApiKeyEntry": { "type": "object", "description": "API key entry for user access summary", "required": [ "key_id", "name", "key_prefix", "owner_type", "owner_id", "is_active", "created_at" ], "properties": { "created_at": { "type": "string", "format": "date-time", "description": "When the key was created" }, "expires_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the key expires (if set)" }, "is_active": { "type": "boolean", "description": "Whether the key is currently active" }, "key_id": { "type": "string", "format": "uuid", "description": "API key ID" }, "key_prefix": { "type": "string", "description": "Key prefix for identification" }, "last_used_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the key was last used" }, "name": { "type": "string", "description": "API key name" }, "owner_id": { "type": "string", "format": "uuid", "description": "Owner ID" }, "owner_type": { "type": "string", "description": "Owner type (organization, project, or user)" }, "revoked_at": { "type": [ "string", "null" ], "format": "date-time", "description": "When the key was revoked (if revoked)" } } }, "UserAccessInventoryEntry": { "type": "object", "description": "Access inventory entry for a single user showing all their access rights", "required": [ "user_id", "external_id", "created_at", "organizations", "projects", "api_key_summary" ], "properties": { "api_key_summary": { "$ref": "#/components/schemas/ApiKeySummary", "description": "Summary of API key ownership" }, "created_at": { "type": "string", "format": "date-time", "description": "When the user was created" }, "email": { "type": [ "string", "null" ], "description": "User's email (if available)" }, "external_id": { "type": "string", "description": "User's external identifier (e.g., from SSO)" }, "last_activity_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last activity timestamp (from audit logs)" }, "name": { "type": [ "string", "null" ], "description": "User's display name (if available)" }, "organizations": { "type": "array", "items": { "$ref": "#/components/schemas/OrgAccessEntry" }, "description": "Organization memberships with access details" }, "projects": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectAccessEntry" }, "description": "Project memberships with access details" }, "user_id": { "type": "string", "format": "uuid", "description": "User ID" } } }, "UserAccessOrgEntry": { "type": "object", "description": "Organization access entry for user access summary", "required": [ "org_id", "org_slug", "org_name", "role", "granted_at" ], "properties": { "granted_at": { "type": "string", "format": "date-time", "description": "When the user was granted access (joined)" }, "last_activity_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last activity in this organization" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization ID" }, "org_name": { "type": "string", "description": "Organization name" }, "org_slug": { "type": "string", "description": "Organization slug" }, "role": { "type": "string", "description": "User's role in the organization" } } }, "UserAccessProjectEntry": { "type": "object", "description": "Project access entry for user access summary", "required": [ "project_id", "project_slug", "project_name", "org_id", "org_slug", "role", "granted_at" ], "properties": { "granted_at": { "type": "string", "format": "date-time", "description": "When the user was granted access (joined)" }, "last_activity_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last activity in this project" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization ID the project belongs to" }, "org_slug": { "type": "string", "description": "Organization slug the project belongs to" }, "project_id": { "type": "string", "format": "uuid", "description": "Project ID" }, "project_name": { "type": "string", "description": "Project name" }, "project_slug": { "type": "string", "description": "Project slug" }, "role": { "type": "string", "description": "User's role in the project" } } }, "UserAccessSummary": { "type": "object", "description": "Summary statistics for user access", "required": [ "total_organizations", "total_projects", "active_api_keys", "revoked_api_keys", "expired_api_keys" ], "properties": { "active_api_keys": { "type": "integer", "format": "int64", "description": "Number of active API keys" }, "expired_api_keys": { "type": "integer", "format": "int64", "description": "Number of expired API keys" }, "revoked_api_keys": { "type": "integer", "format": "int64", "description": "Number of revoked API keys" }, "total_organizations": { "type": "integer", "format": "int64", "description": "Total number of organizations the user belongs to" }, "total_projects": { "type": "integer", "format": "int64", "description": "Total number of projects the user belongs to" } } }, "UserAccessSummaryQuery": { "type": "object", "description": "Query parameters for user access summary endpoint", "properties": { "format": { "$ref": "#/components/schemas/ExportFormat", "description": "Export format (json or csv)" } } }, "UserAccessSummaryResponse": { "type": "object", "description": "User access summary response for access reviews", "required": [ "generated_at", "user_id", "external_id", "created_at", "organizations", "projects", "api_keys", "summary" ], "properties": { "api_keys": { "type": "array", "items": { "$ref": "#/components/schemas/UserAccessApiKeyEntry" }, "description": "API keys owned by the user" }, "created_at": { "type": "string", "format": "date-time", "description": "When the user was created" }, "email": { "type": [ "string", "null" ], "description": "User's email (if available)" }, "external_id": { "type": "string", "description": "User's external identifier" }, "generated_at": { "type": "string", "format": "date-time", "description": "When this summary was generated" }, "last_activity_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last activity timestamp (from audit logs)" }, "name": { "type": [ "string", "null" ], "description": "User's name (if available)" }, "organizations": { "type": "array", "items": { "$ref": "#/components/schemas/UserAccessOrgEntry" }, "description": "Organization memberships with access details" }, "projects": { "type": "array", "items": { "$ref": "#/components/schemas/UserAccessProjectEntry" }, "description": "Project memberships with access details" }, "summary": { "$ref": "#/components/schemas/UserAccessSummary", "description": "Summary statistics" }, "user_id": { "type": "string", "format": "uuid", "description": "User ID" } } }, "UserDataExport": { "type": "object", "description": "Complete user data export (GDPR Article 15 - Right of Access)", "required": [ "exported_at", "user", "memberships", "api_keys", "conversations", "sessions", "usage_summary", "audit_logs" ], "properties": { "api_keys": { "type": "array", "items": { "$ref": "#/components/schemas/ExportedApiKey" }, "description": "API keys owned by the user (excludes sensitive key hash)" }, "audit_logs": { "type": "array", "items": { "$ref": "#/components/schemas/AuditLog" }, "description": "Audit logs where user was the actor (actions performed)" }, "conversations": { "type": "array", "items": { "$ref": "#/components/schemas/Conversation" }, "description": "Conversations owned by the user" }, "exported_at": { "type": "string", "format": "date-time", "description": "When this export was generated" }, "memberships": { "$ref": "#/components/schemas/UserMemberships", "description": "Organization and project memberships" }, "sessions": { "type": "array", "items": { "$ref": "#/components/schemas/ExportedSession" }, "description": "Active sessions (when enhanced session management is enabled)" }, "usage_summary": { "$ref": "#/components/schemas/ExportedUsageSummary", "description": "Aggregated usage summary" }, "user": { "$ref": "#/components/schemas/User", "description": "User profile information" } } }, "UserDeletionResponse": { "type": "object", "description": "Result of a user deletion operation (GDPR Article 17 - Right to Erasure)", "required": [ "deleted", "user_id", "api_keys_deleted", "conversations_deleted", "dynamic_providers_deleted", "usage_records_deleted" ], "properties": { "api_keys_deleted": { "type": "integer", "format": "int64", "description": "Number of API keys deleted", "minimum": 0 }, "conversations_deleted": { "type": "integer", "format": "int64", "description": "Number of conversations deleted", "minimum": 0 }, "deleted": { "type": "boolean", "description": "Whether the user was successfully deleted" }, "dynamic_providers_deleted": { "type": "integer", "format": "int64", "description": "Number of dynamic providers deleted", "minimum": 0 }, "usage_records_deleted": { "type": "integer", "format": "int64", "description": "Number of usage records deleted", "minimum": 0 }, "user_id": { "type": "string", "format": "uuid", "description": "ID of the deleted user" } } }, "UserInfo": { "type": "object", "description": "Database user information.", "required": [ "id", "external_id", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time", "description": "When the user was created in the database" }, "email": { "type": [ "string", "null" ], "description": "Email address" }, "external_id": { "type": "string", "description": "External identity ID (links to IdP)" }, "id": { "type": "string", "format": "uuid", "description": "Internal user ID" }, "name": { "type": [ "string", "null" ], "description": "Display name" }, "updated_at": { "type": "string", "format": "date-time", "description": "When the user was last updated" } } }, "UserListResponse": { "type": "object", "description": "Paginated list of users", "required": [ "data", "pagination" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/User" }, "description": "List of users" }, "pagination": { "$ref": "#/components/schemas/PaginationMeta", "description": "Pagination metadata" } } }, "UserMemberships": { "type": "object", "description": "User memberships (organizations, teams, and projects)", "required": [ "organizations", "teams", "projects" ], "properties": { "organizations": { "type": "array", "items": { "$ref": "#/components/schemas/UserOrgMembership" }, "description": "Organizations the user belongs to" }, "projects": { "type": "array", "items": { "$ref": "#/components/schemas/UserProjectMembership" }, "description": "Projects the user belongs to" }, "teams": { "type": "array", "items": { "$ref": "#/components/schemas/TeamMembership" }, "description": "Teams the user belongs to" } } }, "UserOrgMembership": { "type": "object", "description": "Organization membership for a user", "required": [ "org_id", "org_slug", "org_name", "role", "source", "joined_at" ], "properties": { "joined_at": { "type": "string", "format": "date-time", "description": "When the user joined the organization" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization ID" }, "org_name": { "type": "string", "description": "Organization name" }, "org_slug": { "type": "string", "description": "Organization slug" }, "role": { "type": "string", "description": "User's role in the organization" }, "source": { "$ref": "#/components/schemas/MembershipSource", "description": "Source of this membership (manual, jit, scim)" } } }, "UserProjectMembership": { "type": "object", "description": "Project membership for a user", "required": [ "project_id", "project_slug", "project_name", "org_id", "role", "source", "joined_at" ], "properties": { "joined_at": { "type": "string", "format": "date-time", "description": "When the user joined the project" }, "org_id": { "type": "string", "format": "uuid", "description": "Organization ID the project belongs to" }, "project_id": { "type": "string", "format": "uuid", "description": "Project ID" }, "project_name": { "type": "string", "description": "Project name" }, "project_slug": { "type": "string", "description": "Project slug" }, "role": { "type": "string", "description": "User's role in the project" }, "source": { "$ref": "#/components/schemas/MembershipSource", "description": "Source of this membership (manual, jit, scim)" } } }, "UserSpendResponse": { "type": "object", "description": "Usage breakdown by user", "required": [ "total_cost", "input_tokens", "output_tokens", "total_tokens", "request_count", "image_count", "audio_seconds", "character_count" ], "properties": { "audio_seconds": { "type": "integer", "format": "int64" }, "character_count": { "type": "integer", "format": "int64" }, "image_count": { "type": "integer", "format": "int64" }, "input_tokens": { "type": "integer", "format": "int64" }, "output_tokens": { "type": "integer", "format": "int64" }, "request_count": { "type": "integer", "format": "int64" }, "total_cost": { "type": "number", "format": "double", "description": "Total cost in dollars" }, "total_tokens": { "type": "integer", "format": "int64" }, "user_email": { "type": [ "string", "null" ], "description": "User email" }, "user_id": { "type": [ "string", "null" ], "description": "User ID (null for unattributed usage)" }, "user_name": { "type": [ "string", "null" ], "description": "User display name" } } }, "ValidateCelRequest": { "type": "object", "description": "Request to validate a CEL expression", "required": [ "condition" ], "properties": { "condition": { "type": "string", "description": "CEL expression to validate" } } }, "ValidateCelResponse": { "type": "object", "description": "Response from CEL validation", "required": [ "valid" ], "properties": { "error": { "type": [ "string", "null" ], "description": "Error message if invalid" }, "valid": { "type": "boolean", "description": "Whether the expression is valid" } } }, "Value": {}, "VectorStore": { "type": "object", "description": "A vector store for RAG.\n\nFollows OpenAI VectorStore schema with Hadrian extensions for multi-tenancy\nand embedding configuration.\n\n## Hadrian Extensions\n\nThe following fields are **Hadrian extensions** not present in the standard OpenAI API:\n- `owner_type`, `owner_id`: Multi-tenancy support (organization, project, or user ownership)\n- `description`: Human-readable description of the vector store\n- `embedding_model`: The embedding model used for this vector store (immutable after creation)\n- `embedding_dimensions`: Vector dimensions for the embedding model (immutable after creation)\n- `updated_at`: Timestamp of last modification\n\n## OpenAI Compatibility Notes\n\n- `id` is serialized with `vs_` prefix (e.g., `vs_550e8400-e29b-41d4-a716-446655440000`)\n- `created_at` uses ISO 8601 format (OpenAI uses Unix timestamps)\n- `expires_at`, `last_active_at` use ISO 8601 format (OpenAI uses Unix timestamps)", "required": [ "id", "owner_type", "owner_id", "name", "status", "embedding_model", "embedding_dimensions", "usage_bytes", "file_counts", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "description": { "type": [ "string", "null" ], "description": "**Hadrian Extension:** Human-readable description" }, "embedding_dimensions": { "type": "integer", "format": "int32", "description": "**Hadrian Extension:** Embedding dimensions for this vector store (immutable after creation)" }, "embedding_model": { "type": "string", "description": "**Hadrian Extension:** Embedding model used for this vector store (immutable after creation)" }, "expires_after": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ExpiresAfter" } ] }, "expires_at": { "type": [ "string", "null" ], "format": "date-time" }, "file_counts": { "$ref": "#/components/schemas/FileCounts" }, "id": { "type": "string", "description": "Vector store ID (serialized with `vs_` prefix for OpenAI compatibility)", "example": "vs_550e8400-e29b-41d4-a716-446655440000" }, "last_active_at": { "type": [ "string", "null" ], "format": "date-time" }, "metadata": { "type": [ "object", "null" ], "additionalProperties": {}, "propertyNames": { "type": "string" } }, "name": { "type": "string" }, "object": { "type": "string", "description": "Object type identifier (always \"vector_store\" for API compatibility)" }, "owner_id": { "type": "string", "format": "uuid", "description": "**Hadrian Extension:** Owner ID for multi-tenancy" }, "owner_type": { "$ref": "#/components/schemas/VectorStoreOwnerType", "description": "**Hadrian Extension:** Owner type for multi-tenancy (organization, project, or user)" }, "status": { "$ref": "#/components/schemas/VectorStoreStatus" }, "updated_at": { "type": "string", "format": "date-time", "description": "**Hadrian Extension:** Timestamp of last modification" }, "usage_bytes": { "type": "integer", "format": "int64", "description": "Total storage usage in bytes across all files in this vector store.\n\nThis represents the sum of chunk text content sizes (not including embedding vectors).\nIt may differ from the sum of original file sizes due to chunking and text extraction.\nUpdated automatically when files are processed." } } }, "VectorStoreFile": { "type": "object", "description": "A file in a vector store (links File to VectorStore).\n\nFollows OpenAI VectorStoreFile schema with Hadrian extensions.\n\n## Hadrian Extensions\n\nThe following fields are **Hadrian extensions** not present in the standard OpenAI API:\n- `internal_id`: Internal junction record ID (not serialized, used for database operations)\n- `updated_at`: Timestamp of last modification\n\n## OpenAI Compatibility Notes\n\n- `id` is the Files API file ID (matches OpenAI behavior where the vector store file ID\n is the same as the underlying file ID)\n- `vector_store_id` is serialized with `vs_` prefix\n- `created_at` uses ISO 8601 format (OpenAI uses Unix timestamps)\n- `last_error` is optional (OpenAI requires it, can be null)", "required": [ "id", "vector_store_id", "status", "usage_bytes", "created_at", "updated_at" ], "properties": { "attributes": { "type": [ "object", "null" ], "additionalProperties": {}, "propertyNames": { "type": "string" } }, "chunking_strategy": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ChunkingStrategy" } ] }, "created_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "description": "Vector store file ID - this is the Files API file ID (matches OpenAI behavior)", "example": "file-550e8400-e29b-41d4-a716-446655440000" }, "last_error": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/FileError" } ] }, "object": { "type": "string", "description": "Object type identifier (always \"vector_store.file\" for API compatibility)" }, "status": { "$ref": "#/components/schemas/VectorStoreFileStatus" }, "updated_at": { "type": "string", "format": "date-time", "description": "**Hadrian Extension:** Timestamp of last modification" }, "usage_bytes": { "type": "integer", "format": "int64", "description": "Storage usage in bytes for this file's chunks.\n\nThis represents the sum of chunk text content sizes (not including embedding vectors).\nIt may differ from the original file size due to chunking and text extraction.\nSet to 0 until processing completes." }, "vector_store_id": { "type": "string", "description": "The vector store this file belongs to (vector_store_id in OpenAI API)", "example": "vs_550e8400-e29b-41d4-a716-446655440000" } } }, "VectorStoreFileListResponse": { "type": "object", "description": "Paginated list of vector store files response (OpenAI-compatible).", "required": [ "object", "data", "has_more" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/VectorStoreFile" }, "description": "List of vector store files" }, "first_id": { "type": [ "string", "null" ], "description": "ID of the first file in the list" }, "has_more": { "type": "boolean", "description": "Whether there are more results available" }, "last_id": { "type": [ "string", "null" ], "description": "ID of the last file in the list" }, "object": { "type": "string", "description": "Object type (always \"list\")" } } }, "VectorStoreFileStatus": { "type": "string", "description": "File processing status within a vector store (OpenAI VectorStoreFile compatible)\n\nTracks the processing state when a file is added to a vector store.\nThis is separate from `FileStatus` which tracks the file upload itself.\n\n## State Transitions\n\n```text\n ┌─────────────┐\n success │ completed │\n ┌─────────────────▶└─────────────┘\n │\n┌─────────────┐\n│ in_progress │──────────────▶┌─────────────┐\n└─────────────┘ error │ failed │\n │ └─────────────┘\n │\n │ user request ┌─────────────┐\n └─────────────────▶│ cancelled │\n └─────────────┘\n```\n\n- `in_progress`: File is being chunked and embeddings are being generated\n- `completed`: File successfully processed, chunks stored in vector store\n- `failed`: Processing failed (see `last_error` for details)\n- `cancelled`: Processing was cancelled by user request", "enum": [ "in_progress", "completed", "cancelled", "failed" ] }, "VectorStoreListResponse": { "type": "object", "description": "Paginated list of vector stores response (OpenAI-compatible).", "required": [ "object", "data", "has_more" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/VectorStore" }, "description": "List of vector stores" }, "first_id": { "type": [ "string", "null" ], "description": "ID of the first object in the list (for backward pagination with `before`)" }, "has_more": { "type": "boolean", "description": "Whether there are more results available beyond this page" }, "last_id": { "type": [ "string", "null" ], "description": "ID of the last object in the list (for forward pagination with `after`)" }, "object": { "type": "string", "description": "Object type (always \"list\")" } } }, "VectorStoreOwner": { "oneOf": [ { "type": "object", "required": [ "organization_id", "type" ], "properties": { "organization_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "organization" ] } } }, { "type": "object", "required": [ "team_id", "type" ], "properties": { "team_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "team" ] } } }, { "type": "object", "required": [ "project_id", "type" ], "properties": { "project_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "enum": [ "project" ] } } }, { "type": "object", "required": [ "user_id", "type" ], "properties": { "type": { "type": "string", "enum": [ "user" ] }, "user_id": { "type": "string", "format": "uuid" } } } ], "description": "Owner specification for creating a vector store" }, "VectorStoreOwnerType": { "type": "string", "description": "Owner type for collections (organization, team, project, or user)", "enum": [ "organization", "team", "project", "user" ] }, "VectorStoreSearchRequest": { "type": "object", "description": "Search request for a vector store.\n\n## Ranking Options\n\nUse `ranking_options` to control result scoring and filtering:\n- `ranker`: Algorithm for ranking results\n - `auto` (default): Automatically selects best ranker; supports hybrid search\n - `vector`: Vector-only cosine similarity search\n - `hybrid`: Combines vector and keyword search with RRF fusion\n - `llm`: LLM-based re-ranking for highest quality results\n - `none`: No re-ranking, raw similarity order\n- `score_threshold`: Minimum similarity score (0.0-1.0, default: 0.0)\n- `hybrid_search`: Enable hybrid search combining vector and keyword search\n - `embedding_weight`: Weight for semantic (vector) search (default: 1.0)\n - `text_weight`: Weight for keyword (full-text) search (default: 1.0)\n\n## Hybrid Search Example\n\n```json\n{\n \"query\": \"API authentication\",\n \"ranking_options\": {\n \"ranker\": \"hybrid\",\n \"score_threshold\": 0.5,\n \"hybrid_search\": {\n \"embedding_weight\": 0.7,\n \"text_weight\": 0.3\n }\n }\n}\n```\n\n## LLM Re-ranking Example\n\n```json\n{\n \"query\": \"How to authenticate API requests\",\n \"ranking_options\": {\n \"ranker\": \"llm\",\n \"score_threshold\": 0.5\n }\n}\n```", "required": [ "query" ], "properties": { "filters": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AttributeFilter", "description": "A filter to apply based on file attributes. Supports comparison operators\n(eq, ne, gt, gte, lt, lte) and logical operators (and, or) for combining filters.\n\nExample: `{\"type\": \"eq\", \"key\": \"category\", \"value\": \"documentation\"}`" } ] }, "max_num_results": { "type": [ "integer", "null" ], "description": "Maximum number of results to return (default: 10, max: 50).", "minimum": 0 }, "query": { "type": "string", "description": "The search query text." }, "ranking_options": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/FileSearchRankingOptions", "description": "Ranking options for controlling result scoring and filtering.\n\nIf not specified, uses default ranking with score_threshold of 0.0 (return all results)." } ] } } }, "VectorStoreSearchResponse": { "type": "object", "description": "Search response from a vector store.\n\n## OpenAI Compatibility Notes\n\n- `object` is \"vector_store.search_results\"; OpenAI uses \"vector_store.search_results.page\"\n- `query` is a string; OpenAI uses `search_query` as an array of strings\n- `has_more` and `next_page` pagination fields are not yet supported", "required": [ "object", "query", "data" ], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/SearchResultItem" }, "description": "Search results ordered by relevance (highest first)" }, "object": { "type": "string", "description": "Object type. Note: OpenAI uses \"vector_store.search_results.page\"." }, "query": { "type": "string", "description": "**Hadrian Extension:** The search query that was used. Note: OpenAI uses `search_query` as an array." } } }, "VectorStoreStatus": { "type": "string", "description": "VectorStore (vector store) status (OpenAI VectorStore compatible)\n\nIndicates whether the vector store is ready for use.\n\n## State Transitions\n\n```text\n┌─────────────┐ files processed ┌─────────────┐\n│ in_progress │ ───────────────────────▶│ completed │\n└─────────────┘ └─────────────┘\n │\n │ expiration policy\n │ triggered\n ▼\n ┌─────────────┐\n │ expired │\n └─────────────┘\n```\n\n- `in_progress`: At least one file is being processed (chunked/embedded)\n- `completed`: All files processed successfully, vector store ready for search\n- `expired`: Vector store expired per `expires_after` policy (based on `last_active_at`)", "enum": [ "in_progress", "completed", "expired" ] }, "VerifyDomainResponse": { "type": "object", "description": "Response from a verification attempt.", "required": [ "verified", "message", "verification" ], "properties": { "dns_record_found": { "type": [ "string", "null" ], "description": "The DNS TXT record that was found (if any)" }, "message": { "type": "string", "description": "Human-readable message explaining the result" }, "verification": { "$ref": "#/components/schemas/DomainVerification", "description": "Updated verification record" }, "verified": { "type": "boolean", "description": "Whether the verification succeeded" } } }, "VideoUrl": { "type": "object", "description": "Video URL reference", "required": [ "url" ], "properties": { "url": { "type": "string" } } }, "Voice": { "type": "string", "description": "Voice options for text-to-speech.", "enum": [ "alloy", "ash", "ballad", "coral", "echo", "fable", "nova", "onyx", "sage", "shimmer", "verse", "marin", "cedar" ] }, "WebFetchRequest": { "type": "object", "required": [ "url" ], "properties": { "max_length": { "type": [ "integer", "null" ], "minimum": 0 }, "url": { "type": "string" } } }, "WebFetchResponse": { "type": "object", "required": [ "url", "content", "content_length" ], "properties": { "content": { "type": "string" }, "content_length": { "type": "integer", "minimum": 0 }, "content_type": { "type": [ "string", "null" ] }, "url": { "type": "string" } } }, "WebSearch20250826Tool": { "type": "object", "required": [ "type" ], "properties": { "cache_control": { "type": [ "object", "null" ], "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" }, "filters": { "type": [ "object", "null" ] }, "search_context_size": { "type": [ "string", "null" ] }, "type": { "$ref": "#/components/schemas/WebSearch20250826ToolType" }, "user_location": { "type": [ "object", "null" ] } } }, "WebSearch20250826ToolType": { "type": "string", "enum": [ "web_search_2025_08_26" ] }, "WebSearchPreview20250311Tool": { "type": "object", "required": [ "type" ], "properties": { "cache_control": { "type": [ "object", "null" ], "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" }, "search_context_size": { "type": [ "string", "null" ] }, "type": { "$ref": "#/components/schemas/WebSearchPreview20250311ToolType" }, "user_location": { "type": [ "object", "null" ] } } }, "WebSearchPreview20250311ToolType": { "type": "string", "enum": [ "web_search_preview_2025_03_11" ] }, "WebSearchPreviewTool": { "type": "object", "required": [ "type" ], "properties": { "cache_control": { "type": [ "object", "null" ], "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" }, "search_context_size": { "type": [ "string", "null" ] }, "type": { "$ref": "#/components/schemas/WebSearchPreviewToolType" }, "user_location": { "type": [ "object", "null" ] } } }, "WebSearchPreviewToolType": { "type": "string", "enum": [ "web_search_preview" ] }, "WebSearchRequest": { "type": "object", "required": [ "query" ], "properties": { "max_results": { "type": [ "integer", "null" ], "minimum": 0 }, "query": { "type": "string" } } }, "WebSearchResponse": { "type": "object", "required": [ "results" ], "properties": { "results": { "type": "array", "items": { "$ref": "#/components/schemas/WebSearchResult" } } } }, "WebSearchResult": { "type": "object", "required": [ "title", "url", "content" ], "properties": { "content": { "type": "string" }, "score": { "type": [ "number", "null" ], "format": "double" }, "title": { "type": "string" }, "url": { "type": "string" } } }, "WebSearchTool": { "type": "object", "required": [ "type" ], "properties": { "cache_control": { "type": [ "object", "null" ], "description": "**Hadrian Extension:** Cache control for prompt caching (Anthropic/Bedrock)" }, "filters": { "type": [ "object", "null" ] }, "search_context_size": { "type": [ "string", "null" ] }, "type": { "$ref": "#/components/schemas/WebSearchToolType" }, "user_location": { "type": [ "object", "null" ] } } }, "WebSearchToolType": { "type": "string", "enum": [ "web_search" ] } }, "securitySchemes": { "api_key": { "type": "http", "scheme": "bearer", "bearerFormat": "API Key", "description": "API key authentication using Bearer token format" } } }, "security": [ { "api_key": [] } ], "tags": [ { "name": "chat", "description": "Create chat completions using conversational message format. Supports streaming, tool use, vision, and reasoning models. OpenAI-compatible." }, { "name": "completions", "description": "Create text completions from a prompt. Legacy API for non-chat models. OpenAI-compatible." }, { "name": "embeddings", "description": "Generate vector embeddings for text input. Use for semantic search, clustering, and similarity comparisons. OpenAI-compatible." }, { "name": "models", "description": "List all available models from configured providers. Model IDs are prefixed with provider name." }, { "name": "me", "description": "Self-service endpoints for authenticated users. Export personal data for GDPR compliance." }, { "name": "oauth", "description": "OAuth-style PKCE flow for issuing user-scoped API keys to external apps. The user grants consent in the Hadrian UI; the external app exchanges the resulting code at `/oauth/token` for an API key bound to that user." }, { "name": "Images", "description": "Generate, edit, and create variations of images using DALL-E models. OpenAI-compatible." }, { "name": "Audio", "description": "Text-to-speech, speech-to-text transcription, and audio translation using TTS and Whisper models. OpenAI-compatible." }, { "name": "organizations", "description": "Organizations are the top-level entity for multi-tenancy. Each organization can have multiple projects, users, API keys, and provider configurations." }, { "name": "projects", "description": "Projects belong to organizations and provide a way to separate workloads, budgets, and API keys within an organization." }, { "name": "users", "description": "Users can be members of organizations and projects. Users can have their own API keys and provider configurations." }, { "name": "api-keys", "description": "API keys authenticate requests to the Public API. Keys can be scoped to organizations, projects, or users with optional budget limits and expiration." }, { "name": "dynamic-providers", "description": "Dynamic providers allow runtime configuration of LLM backends without restarting the gateway. Useful for BYOK (bring-your-own-key) scenarios." }, { "name": "usage", "description": "Query usage statistics for API keys including token counts, costs, and breakdowns by date, model, or referer." }, { "name": "model-pricing", "description": "Configure per-model pricing for cost tracking. Pricing can be set globally, per-provider, per-organization, per-project, or per-user." }, { "name": "conversations", "description": "Store and manage chat conversation history. Conversations can be owned by users or projects and support multiple models." }, { "name": "templates", "description": "Manage reusable prompt templates. Templates can be owned by organizations, teams, projects, or users and include metadata for configuration." }, { "name": "skills", "description": "Manage Agent Skills (https://agentskills.io). A skill packages a SKILL.md instruction file plus optional bundled scripts, references, and assets. Skills can be user-invoked via slash command or auto-invoked by the model via the frontend Skill tool." }, { "name": "audit-logs", "description": "Query audit logs for admin operations. All sensitive operations like API key creation, user permission changes, and resource modifications are logged." }, { "name": "teams", "description": "Teams group users within an organization for easier permission management. Users can belong to multiple teams, and projects can be assigned to a team." }, { "name": "service_accounts", "description": "Service accounts are machine identities that can own API keys and carry roles for RBAC evaluation. They enable unified authorization across human users and automated systems." }, { "name": "access-reviews", "description": "Access review reports for compliance requirements (SOC 2, ISO 27001). View user access across organizations, projects, and API keys." }, { "name": "sso", "description": "SSO connection configuration (read-only from config). View OIDC and proxy auth settings for JIT user provisioning." }, { "name": "files", "description": "Upload and manage files for use with vector stores. Files are uploaded via multipart form data and can be added to vector stores for RAG." }, { "name": "vector-stores", "description": "Create and manage vector stores for RAG (Retrieval Augmented Generation). Vector stores contain files that are chunked and embedded for semantic search.\n\n## Hadrian Extensions\n\nThe Vector Stores API is based on OpenAI's Vector Stores API with the following extensions:\n\n### Multi-Tenancy\n- `owner_type`, `owner_id` fields for organization/project/user ownership\n- Required in create requests and included in responses\n\n### Additional Fields\n- `description`: Human-readable description for vector stores\n- `embedding_model`: Configurable embedding model (default: text-embedding-3-small)\n- `embedding_dimensions`: Configurable vector dimensions (default: 1536)\n- `updated_at`: Modification timestamp\n- `file_id`: Reference to Files API in vector store files\n\n### Extension Endpoints\n- `GET /v1/vector_stores/{id}/files/{file_id}/chunks`: List chunks for debugging\n\n### Search Extensions\n- Request: `threshold` (similarity threshold), `file_ids` (file filter)\n- Response: `chunk_id`, `vector_store_id`, `chunk_index` for debugging\n\n### Schema Differences\n- Timestamps use ISO 8601 format (OpenAI uses Unix timestamps)\n- List responses use `pagination` object (OpenAI uses root-level `first_id`, `last_id`, `has_more`)\n- Search `content` is a string (OpenAI uses `[{type, text}]` array)" }, { "name": "health", "description": "Health check endpoints for monitoring and Kubernetes probes. Use `/health` for detailed status, `/health/live` for liveness probes, and `/health/ready` for readiness probes." }, { "name": "auth", "description": "Browser-facing authentication endpoints (OIDC / SAML). The frontend calls `/auth/discover` to find the right SSO provider for an email domain, then `/auth/login` to redirect to the IdP; `/auth/me` returns the authenticated identity for whatever session cookie or bearer token is presented." } ], "x-tagGroups": [ { "name": "Health & Infrastructure", "tags": [ "health" ] }, { "name": "Public API", "tags": [ "chat", "completions", "embeddings", "models" ] }, { "name": "Admin API", "tags": [ "organizations", "projects", "teams", "users", "api-keys", "dynamic-providers", "usage", "model-pricing", "conversations", "dlq", "audit-logs", "access-reviews", "sso", "files", "vector-stores" ] } ] }