{"openapi":"3.1.0","info":{"title":"Scalix Cloud API","description":"One platform, one token, one API — database, compute, AI inference, storage, and functions.\n\nConventions:\n- **Auth**: `Authorization: Bearer scalix_sk_…` on every request. `GET /v1/me` returns the key's identity, scopes, and enforced rate limits.\n- **Errors**: JSON envelope `{code, error, docs_url, request_id}`; every response carries an `x-request-id` header.\n- **Rate limits**: `x-ratelimit-limit` / `x-ratelimit-remaining` / `x-ratelimit-reset` response headers.\n- **Idempotency**: mutating requests under `/v1/storage`, `/v1/functions`, `/v1/services`, `/v1/run/services`, `/v1/kv`, and `/v1/events` accept an `Idempotency-Key` header — retries with the same key within 24h replay the original response instead of re-executing.","contact":{"name":"Scalix World","url":"https://scalix.world"},"license":{"name":"BUSL-1.1"},"version":"1.5.0"},"servers":[{"url":"https://api.scalix.world","description":"Production"},{"url":"http://localhost:8080","description":"Local development"}],"paths":{"/api/v1/anomalies":{"post":{"tags":["Database"],"summary":"Detect database anomalies.","description":"Analyzes recent activity and returns a report of detected database anomalies.","operationId":"detectAnomalies","responses":{"200":{"description":"Anomaly report"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/encryption/decrypt":{"post":{"tags":["Encryption"],"summary":"Decrypt data.","description":"Decrypts the supplied ciphertext and returns the plaintext.","operationId":"decryptData","responses":{"200":{"description":"Decrypted plaintext"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/encryption/encrypt":{"post":{"tags":["Encryption"],"summary":"Encrypt data.","description":"Encrypts the supplied plaintext and returns the ciphertext.","operationId":"encryptData","responses":{"200":{"description":"Encrypted ciphertext"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/encryption/rotate-key":{"post":{"tags":["Encryption"],"summary":"Rotate the encryption key.","description":"Rotates the tenant's encryption key.","operationId":"rotateEncryptionKey","responses":{"200":{"description":"Key rotated"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/mcp":{"get":{"tags":["MCP"],"summary":"List MCP tools.","description":"Returns the MCP tool definitions available to the caller.","operationId":"listMcpTools","responses":{"200":{"description":"Tool definitions"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/mcp/call":{"post":{"tags":["MCP"],"summary":"Call an MCP tool.","description":"Invokes an MCP tool and returns its result.","operationId":"callMcpTool","responses":{"200":{"description":"Tool result"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/nl-to-sql":{"post":{"tags":["Database"],"summary":"Translate natural language to SQL.","description":"Generates a SQL statement from a natural-language description of the desired query.","operationId":"naturalLanguageToSql","responses":{"200":{"description":"Generated SQL"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/optimize":{"post":{"tags":["Database"],"summary":"Get query optimization suggestions.","description":"Analyzes the tenant's database and returns indexing and query optimization suggestions.","operationId":"optimizeQuery","responses":{"200":{"description":"Optimization suggestions"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/query-logs/{tenant_id}":{"get":{"tags":["Database"],"summary":"List recent query logs.","description":"Returns recent query-log entries for a tenant, newest first.","operationId":"listQueryLogs","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max entries to return (default 100, max 1000)","required":false,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Recent query log entries"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/scaling":{"get":{"tags":["Database"],"summary":"Get scaling suggestions.","description":"Returns capacity and scaling recommendations for the tenant's database.","operationId":"getScalingSuggestions","responses":{"200":{"description":"Scaling suggestions"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/schema":{"get":{"tags":["Schema"],"summary":"Get the database schema.","description":"Returns the tables, views, and types in the tenant's database.","operationId":"getSchema","responses":{"200":{"description":"Schema information"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/schema/columns":{"get":{"tags":["Schema"],"summary":"Search schema columns.","description":"Returns columns across the schema matching an optional name search term.","operationId":"searchSchemaColumns","parameters":[{"name":"q","in":"query","description":"Column-name search term","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Matching columns"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/schema/pii":{"get":{"tags":["Schema"],"summary":"Analyze PII columns.","description":"Returns columns flagged as likely personally identifiable information.","operationId":"listPiiColumns","responses":{"200":{"description":"PII column analysis"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/schema/relationships":{"get":{"tags":["Schema"],"summary":"List schema relationships.","description":"Returns the foreign-key relationships between tables in the schema.","operationId":"getSchemaRelationships","responses":{"200":{"description":"Foreign key relationships"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/schema/table/{name}":{"get":{"tags":["Schema"],"summary":"Get a table's schema.","description":"Returns the columns and types for a single table.","operationId":"getTableSchema","parameters":[{"name":"name","in":"path","description":"Table name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Table columns and types"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/services":{"get":{"tags":["System"],"summary":"Get service status.","description":"Returns the operational status of Scalix Cloud services.","operationId":"getServicesStatus","responses":{"200":{"description":"Service status"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/sql":{"post":{"tags":["Database"],"summary":"Execute a SQL query.","description":"Runs a parameterized SQL statement against the tenant's database and returns the result set.","operationId":"executeSql","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SqlRequest"}}},"required":true},"responses":{"200":{"description":"Query results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SqlResponse"}}}},"400":{"description":"Invalid SQL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/sql/batch":{"post":{"tags":["Database"],"summary":"Execute a batch of SQL queries.","description":"Runs multiple SQL statements in one request; each query executes independently and returns its own result set.","operationId":"batchSql","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchSqlRequest"}}},"required":true},"responses":{"200":{"description":"Array of query results"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/migrations":{"post":{"tags":["Migrations"],"summary":"Register a migration.","description":"Registers a database migration for a tenant.","operationId":"registerMigration","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Migration registered"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/migrations/plan":{"get":{"tags":["Migrations"],"summary":"Get the migration plan.","description":"Returns the pending migrations for a tenant.","operationId":"getMigrationPlan","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pending migrations"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/pitr/restore":{"post":{"tags":["PITR"],"summary":"Restore to a point in time.","description":"Initiates a point-in-time restore of a tenant's database.","operationId":"restorePitr","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Restore initiated"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Recovery target is beyond the archived WAL — retry with an earlier target, or omit the target to restore the latest recoverable point","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/realtime/subscribe":{"post":{"tags":["Realtime"],"summary":"Create a realtime subscription.","description":"Creates a realtime subscription for a tenant.","operationId":"subscribeRealtime","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Subscription created"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/realtime/ws":{"get":{"tags":["Realtime"],"summary":"Open a realtime WebSocket.","description":"Upgrades the connection to a realtime WebSocket stream for a tenant.","operationId":"realtimeWebsocket","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"101":{"description":"WebSocket upgrade"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/timelines/{timeline_id}/branch":{"post":{"tags":["PITR"],"summary":"Branch a timeline.","description":"Restores the parent timeline's durable base backup + archived WAL into a\nNEW compute worker replayed to `branch_lsn` (`0` = latest), then routes the\nbranch endpoint. The branch archives onto its own timeline from that point.","operationId":"branchTimeline","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"timeline_id","in":"path","description":"Parent timeline id (UUID), or `main` for the primary timeline","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchTimelineRequest"}}},"required":true},"responses":{"201":{"description":"Branch created and routed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BranchTimelineResponse"}}}},"400":{"description":"Invalid tenant, timeline, or new_timeline_id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Branch LSN is beyond the archived WAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"501":{"description":"Durability is not configured for this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"No compute capacity for the branch worker","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/vectors/batch/upsert":{"post":{"tags":["Vectors"],"summary":"Batch upsert vectors.","description":"Inserts or updates many vectors in a collection in a single request\n(one multi-row write). Returns the number of vectors upserted.","operationId":"batchUpsertVectors","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorUpsertRequest"}}},"required":true},"responses":{"201":{"description":"Vectors upserted (count returned)"},"400":{"description":"Invalid request (e.g. dimension mismatch or batch too large)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Vector store unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/vectors/collections":{"get":{"tags":["Vectors"],"summary":"List vector collections.","description":"Returns the vector collections for a tenant.","operationId":"listVectorCollections","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Collection list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Vectors"],"summary":"Create a vector collection.","description":"Creates a new vector collection for a tenant.","operationId":"createVectorCollection","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Collection created"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/vectors/search":{"post":{"tags":["Vectors"],"summary":"Search vectors.","description":"Runs a nearest-neighbour vector search and returns scored matches.","operationId":"searchVectors","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorSearchRequest"}}},"required":true},"responses":{"200":{"description":"Search results with scores"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/vectors/upsert":{"post":{"tags":["Vectors"],"summary":"Upsert vectors.","description":"Inserts or updates a batch of vectors in a collection.","operationId":"upsertVectors","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorUpsertRequest"}}},"required":true},"responses":{"200":{"description":"Vectors upserted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhooks.","description":"Returns the registered webhook endpoints for a tenant.","operationId":"listWebhooks","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Webhooks"],"summary":"Register a webhook.","description":"Registers a webhook endpoint for a set of event types.","operationId":"registerWebhook","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRequest"}}},"required":true},"responses":{"201":{"description":"Webhook registered"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/webhooks/{id}":{"get":{"tags":["Webhooks"],"summary":"Get a webhook.","description":"Returns one registered webhook by id.","operationId":"getWebhook","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"Webhook id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The webhook"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Webhooks"],"summary":"Update a webhook.","description":"Replaces the endpoint URL, event types, secret, and active flag of a\nregistered webhook.","operationId":"updateWebhook","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"Webhook id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRequest"}}},"required":true},"responses":{"200":{"description":"Webhook updated"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Webhooks"],"summary":"Unregister a webhook.","description":"Deletes a registered webhook; event delivery to its endpoint stops.","operationId":"unregisterWebhook","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"Webhook id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Webhook unregistered"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/webhooks/{id}/deliveries":{"get":{"tags":["Webhooks"],"summary":"List a webhook's deliveries.","description":"Returns recent delivery attempts for a webhook with their outcomes, so\na missed event can be traced to a failed delivery.","operationId":"listWebhookDeliveries","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"Webhook id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent delivery attempts"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenant_id}/webhooks/{id}/test":{"post":{"tags":["Webhooks"],"summary":"Test a webhook.","description":"Sends a test event to the webhook's endpoint and reports the delivery\nresult without waiting for a real event.","operationId":"testWebhook","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","description":"Webhook id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Test event sent; delivery result"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/usage":{"get":{"tags":["Metering"],"summary":"Get usage summary.","description":"Returns the caller's aggregate usage summary.","operationId":"getUsageSummary","responses":{"200":{"description":"Usage summary"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/healthz":{"get":{"tags":["System"],"summary":"Liveness probe.","description":"Returns 200 while the gateway process is alive.","operationId":"healthz","responses":{"200":{"description":"Gateway is alive"}}}},"/openapi.json":{"get":{"tags":["System"],"summary":"Get the OpenAPI spec.","description":"Returns this OpenAPI specification document.","operationId":"getOpenapiSpec","responses":{"200":{"description":"This OpenAPI specification"}}}},"/readyz":{"get":{"tags":["System"],"summary":"Readiness probe.","description":"Returns 200 when the gateway is ready to serve traffic.","operationId":"readyz","responses":{"200":{"description":"Gateway is ready to serve traffic"}}}},"/v1/activity":{"get":{"tags":["Activity"],"summary":"List the activity log.","description":"Requires the `activity:read` scope.","operationId":"listActivity","responses":{"200":{"description":"List the activity log"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing activity:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/audio/speech":{"post":{"tags":["AI"],"summary":"Generate speech.","description":"Synthesizes audio from text (text-to-speech).","operationId":"generateSpeech","requestBody":{"description":"Text-to-speech request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Synthesized audio"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/audio/transcriptions":{"post":{"tags":["AI"],"summary":"Transcribe audio.","description":"Converts an uploaded audio file to text (speech-to-text).","operationId":"transcribeAudio","requestBody":{"description":"Audio transcription request (speech-to-text)","content":{"multipart/form-data":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Transcription result"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/chat/completions":{"post":{"tags":["AI"],"summary":"Create a chat completion.","description":"Runs an OpenAI-compatible chat completion and returns the model's response.","operationId":"chatCompletion","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionRequest"}}},"required":true},"responses":{"200":{"description":"Completion response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Budget exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"All providers exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/chat/completions/stream":{"post":{"tags":["AI"],"summary":"Stream a chat completion.","description":"Runs an OpenAI-compatible chat completion and streams the response as server-sent events.","operationId":"streamChatCompletion","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionRequest"}}},"required":true},"responses":{"200":{"description":"Server-sent event stream of completion chunks"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Budget exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"All providers exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/docgen/create":{"post":{"tags":["AI"],"summary":"Generate a document.","description":"Generates a document from the supplied request.","operationId":"createDocgen","requestBody":{"description":"Document generation request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Generated document"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/docgen/download/{doc_id}":{"get":{"tags":["AI"],"summary":"Download a generated document.","description":"Downloads the generated document file by id.","operationId":"downloadDocgen","parameters":[{"name":"doc_id","in":"path","description":"Document id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Document file download"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/docgen/formats":{"get":{"tags":["AI"],"summary":"List docgen formats.","description":"Returns the output formats supported by document generation.","operationId":"listDocgenFormats","responses":{"200":{"description":"Supported output formats"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/docgen/history":{"get":{"tags":["AI"],"summary":"Get docgen history.","description":"Returns the caller's document-generation history.","operationId":"getDocgenHistory","responses":{"200":{"description":"Document generation history"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/docgen/preview":{"post":{"tags":["AI"],"summary":"Preview a generated document.","description":"Returns a preview of a document without finalizing it.","operationId":"previewDocgen","requestBody":{"description":"Document preview request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Document preview"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/docgen/revise":{"post":{"tags":["AI"],"summary":"Revise a generated document.","description":"Applies revisions to a previously generated document.","operationId":"reviseDocgen","requestBody":{"description":"Document revision request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Revised document"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/docgen/status":{"get":{"tags":["AI"],"summary":"Get docgen status.","description":"Returns the status of the document-generation subsystem.","operationId":"getDocgenStatus","responses":{"200":{"description":"Docgen subsystem status"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/docgen/templates":{"get":{"tags":["AI"],"summary":"List docgen templates.","description":"Returns the available document-generation templates.","operationId":"listDocgenTemplates","responses":{"200":{"description":"Available document templates"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/docgen/versions/{doc_id}":{"get":{"tags":["AI"],"summary":"List document versions.","description":"Returns the version history of a generated document.","operationId":"listDocgenVersions","parameters":[{"name":"doc_id","in":"path","description":"Document id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Document versions"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/embeddings":{"post":{"tags":["AI"],"summary":"Create embeddings.","description":"Generates vector embeddings for the supplied input (OpenAI-compatible).","operationId":"createEmbeddings","requestBody":{"description":"Embeddings request (OpenAI-compatible)","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Embedding vectors"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/images/generations":{"post":{"tags":["AI"],"summary":"Generate images.","description":"Generates one or more images from a text prompt.","operationId":"generateImage","requestBody":{"description":"Image generation request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Generated image(s)"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/models":{"get":{"tags":["AI"],"summary":"List AI models.","description":"Returns the AI models available to the caller.","operationId":"listModels","responses":{"200":{"description":"Model list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/providers/status":{"get":{"tags":["AI"],"summary":"Get AI provider status.","description":"Returns the availability and health of the AI inference providers.","operationId":"getAiProvidersStatus","responses":{"200":{"description":"Provider availability/status"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/rag/documents":{"get":{"tags":["AI"],"summary":"List RAG documents.","description":"Returns the documents indexed for retrieval-augmented generation.","operationId":"listRagDocuments","responses":{"200":{"description":"List of indexed documents"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/rag/documents/{doc_id}":{"delete":{"tags":["AI"],"summary":"Delete a RAG document.","description":"Removes a document from the retrieval-augmented generation index.","operationId":"deleteRagDocument","parameters":[{"name":"doc_id","in":"path","description":"Document id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Document deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/rag/query":{"post":{"tags":["AI"],"summary":"Query RAG documents.","description":"Runs a retrieval-augmented query over indexed documents and returns scored matches.","operationId":"queryRag","requestBody":{"description":"RAG query over indexed documents","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Query results with similarity scores"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/rag/status":{"get":{"tags":["AI"],"summary":"Get RAG status.","description":"Returns the status of the retrieval-augmented generation subsystem.","operationId":"getRagStatus","responses":{"200":{"description":"RAG subsystem status"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/rag/upload":{"post":{"tags":["AI"],"summary":"Upload a RAG document.","description":"Uploads and indexes a document for retrieval-augmented generation.","operationId":"uploadRagDocument","requestBody":{"description":"Document upload (multipart form-data)","content":{"multipart/form-data":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Uploaded document metadata"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/research":{"post":{"tags":["AI"],"summary":"Run web research.","description":"Answers a question using live web research and returns the answer with sources.","operationId":"runResearch","requestBody":{"description":"Web research request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Research answer with sources"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/research/deep":{"post":{"tags":["AI"],"summary":"Run deep web research.","description":"Runs a multi-step deep web research task and returns a synthesized answer with sources.","operationId":"runDeepResearch","requestBody":{"description":"Deep web research request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Deep research answer with sources"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/research/search":{"post":{"tags":["AI"],"summary":"Run a research search.","description":"Performs a web research search and returns matching results.","operationId":"searchResearch","requestBody":{"description":"Web research search query","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Search results"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/research/status":{"get":{"tags":["AI"],"summary":"Get research status.","description":"Returns the status of the web research subsystem.","operationId":"getResearchStatus","responses":{"200":{"description":"Research subsystem status"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/text/autocomplete":{"post":{"tags":["AI"],"summary":"Autocomplete text.","description":"Returns completion suggestions for the supplied text.","operationId":"autocompleteText","requestBody":{"description":"Autocomplete request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Completion suggestions"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/text/grammar":{"post":{"tags":["AI"],"summary":"Check grammar.","description":"Returns grammar corrections for the supplied text.","operationId":"checkGrammar","requestBody":{"description":"Grammar-check request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Grammar corrections"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/text/sentiment":{"post":{"tags":["AI"],"summary":"Analyze sentiment.","description":"Returns the sentiment of the supplied text.","operationId":"analyzeSentiment","requestBody":{"description":"Sentiment analysis request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Sentiment result"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/text/summarize":{"post":{"tags":["AI"],"summary":"Summarize text.","description":"Returns a summary of the supplied text.","operationId":"summarizeText","requestBody":{"description":"Summarization request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Summary"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/text/translate":{"post":{"tags":["AI"],"summary":"Translate text.","description":"Translates the supplied text to a target language.","operationId":"translateText","requestBody":{"description":"Translation request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Translated text"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/ai/text/vector-search":{"post":{"tags":["AI"],"summary":"Run in-context vector search.","description":"Runs a vector similarity search over supplied in-context text.","operationId":"textVectorSearch","requestBody":{"description":"In-context vector search request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Vector search results"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/anonymous":{"post":{"tags":["Auth"],"summary":"Sign in anonymously.","description":"Creates an anonymous end-user account and returns auth tokens; the account\ncan later be linked to a real identity via identity linking.","operationId":"signUpAnonymous","responses":{"201":{"description":"Anonymous account created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/identity/link":{"post":{"tags":["Auth"],"summary":"Link an identity.","description":"Links an additional identity (e.g. an OAuth provider or email/password) to\nthe authenticated user, including upgrading anonymous accounts.","operationId":"linkIdentity","responses":{"200":{"description":"Identity linked"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/login":{"post":{"tags":["Auth"],"summary":"Log in.","description":"Authenticates an end user with email and password and returns auth tokens.","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignInRequest"}}},"required":true},"responses":{"200":{"description":"Login successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"423":{"description":"Account locked due to too many failed attempts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/logout":{"post":{"tags":["Auth"],"summary":"Log out.","description":"Invalidates the caller's current session/token.","operationId":"logout","responses":{"200":{"description":"Logged out"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/magic-link":{"post":{"tags":["Auth"],"summary":"Send a magic link.","description":"Emails the user a passwordless magic sign-in link.","operationId":"sendMagicLink","responses":{"200":{"description":"Magic link sent"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/magic-link/verify":{"post":{"tags":["Auth"],"summary":"Verify a magic link.","description":"Exchanges the emailed magic-link token for Scalix auth tokens.","operationId":"verifyMagicLink","responses":{"200":{"description":"Auth tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/me/orgs":{"get":{"tags":["Auth"],"summary":"List the user's organizations.","description":"Returns the organizations the authenticated end user belongs to.","operationId":"listUserOrgs","responses":{"200":{"description":"Organizations for the current user"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/mfa/challenge":{"post":{"tags":["Auth"],"summary":"Complete an MFA challenge.","description":"Verifies a TOTP code against an enrolled factor during sign-in and returns\nauth tokens.","operationId":"challengeMfa","responses":{"200":{"description":"Auth tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/mfa/enroll":{"post":{"tags":["Auth"],"summary":"Enroll in MFA.","description":"Begins TOTP multi-factor enrollment and returns the secret and QR code.","operationId":"enrollMfa","responses":{"200":{"description":"MFA enrollment data (TOTP secret, QR code)"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/mfa/factors":{"get":{"tags":["Auth"],"summary":"List MFA factors.","description":"Returns the authenticated user's enrolled multi-factor authentication factors.","operationId":"listMfaFactors","responses":{"200":{"description":"Enrolled MFA factors"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/mfa/factors/{id}":{"delete":{"tags":["Auth"],"summary":"Delete an MFA factor.","description":"Removes an enrolled multi-factor authentication factor.","operationId":"deleteMfaFactor","parameters":[{"name":"id","in":"path","description":"MFA factor id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Factor deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/mfa/verify":{"post":{"tags":["Auth"],"summary":"Verify MFA.","description":"Verifies a TOTP code to complete multi-factor enrollment or a challenge.","operationId":"verifyMfa","responses":{"200":{"description":"MFA verified"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/oauth/authorize":{"post":{"tags":["Auth"],"summary":"Start OAuth authorization.","description":"Returns the provider authorization URL to begin an OAuth sign-in flow.","operationId":"authorizeOauth","responses":{"200":{"description":"Authorization URL"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/oauth/callback":{"post":{"tags":["Auth"],"summary":"Complete OAuth sign-in.","description":"Exchanges the provider OAuth callback for Scalix auth tokens.","operationId":"oauthCallback","responses":{"200":{"description":"Auth tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/otp":{"post":{"tags":["Auth"],"summary":"Send a one-time passcode.","description":"Sends the user a one-time passcode for passwordless sign-in.","operationId":"sendOtp","responses":{"200":{"description":"OTP sent"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/otp/verify":{"post":{"tags":["Auth"],"summary":"Verify a one-time passcode.","description":"Exchanges the phone number and OTP code for Scalix auth tokens.","operationId":"verifyOtp","responses":{"200":{"description":"Auth tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/recover":{"post":{"tags":["Auth"],"summary":"Request a password reset.","description":"Emails the user a password-recovery link.","operationId":"requestPasswordReset","responses":{"200":{"description":"Recovery email sent"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/recover/reset":{"put":{"tags":["Auth"],"summary":"Reset the password.","description":"Sets a new password using a recovery token.","operationId":"resetPassword","responses":{"200":{"description":"Password updated"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/refresh":{"post":{"tags":["Auth"],"summary":"Refresh auth tokens.","description":"Exchanges a refresh token for a new access/refresh token pair.","operationId":"refreshToken","responses":{"200":{"description":"New tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/resend-verification":{"post":{"tags":["Auth"],"summary":"Resend the verification email.","description":"Sends the email-verification message again.","operationId":"resendVerification","responses":{"200":{"description":"Verification email sent"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/sessions":{"get":{"tags":["Auth"],"summary":"List sessions.","description":"Returns the authenticated user's active sessions.","operationId":"listSessions","responses":{"200":{"description":"Active sessions"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/sessions/{id}":{"delete":{"tags":["Auth"],"summary":"Revoke a session.","description":"Terminates one of the authenticated user's sessions.","operationId":"revokeSession","parameters":[{"name":"id","in":"path","description":"Session id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Session revoked"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/signup":{"post":{"tags":["Auth"],"summary":"Sign up a new user.","description":"Creates a new end-user account and returns auth tokens plus the created user.","operationId":"signUp","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignUpRequest"}}},"required":true},"responses":{"201":{"description":"Account created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Email already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many signups from this IP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/user":{"get":{"tags":["Auth"],"summary":"Get the current user.","description":"Returns the authenticated end user's profile.","operationId":"getAuthUser","responses":{"200":{"description":"User profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Auth"],"summary":"Update the current user.","description":"Updates the authenticated end user's profile and returns the new record.","operationId":"updateAuthUser","responses":{"200":{"description":"Updated user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/user/consent":{"get":{"tags":["Auth"],"summary":"List consent records.","description":"Returns the authenticated user's consent audit trail.","operationId":"listAuthUserConsent","responses":{"200":{"description":"Consent audit trail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentRecord"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Auth"],"summary":"Record a consent decision.","description":"Records a single GDPR consent decision for the authenticated user.","operationId":"recordAuthUserConsent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordConsentRequest"}}},"required":true},"responses":{"201":{"description":"Consent recorded"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/user/export":{"get":{"tags":["Auth"],"summary":"Export user data.","description":"Returns a complete export of the authenticated user's data (GDPR portability).","operationId":"exportAuthUser","responses":{"200":{"description":"Complete user data export"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/auth/verify":{"post":{"tags":["Auth"],"summary":"Verify an email address.","description":"Confirms the user's email address using the emailed verification token.","operationId":"verifyEmail","responses":{"200":{"description":"Email verified"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/catalog/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get the service catalog.","description":"The billable-service catalog with per-service agreement state for the\norg.","operationId":"getServiceCatalog","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Service catalog with agreement state"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/checkout":{"post":{"tags":["Billing"],"summary":"Start a hosted checkout.","description":"Creates a provider checkout session for the plan upgrade (or first\npaid plan) and returns the URL to send the customer to.","operationId":"createCheckout","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"201":{"description":"Checkout session created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSession"}}}},"400":{"description":"Invalid request (e.g. missing tenant/email, or the free plan)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/credit-ledger/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get the credit ledger.","description":"Returns the org's full credit ledger (the BillingPage's ledger table).","operationId":"getCreditLedger","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Credit ledger"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/credit-transactions/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get credit transactions.","description":"Returns the org's credit transaction list (the BillingPage's\ntransactions table).","operationId":"getCreditTransactions","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Credit transactions"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/credit-usage-metrics/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get per-metric usage cost.","description":"Returns credit consumption broken down by billing metric (the\nusage-by-service view).","operationId":"getUsageCostByMetric","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Usage cost by metric"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/credit-usage/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get credit usage.","description":"Returns the org's credit consumption for the current period.","operationId":"getCreditUsage","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Credit usage for the period"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/credits/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get the credit balance.","description":"Returns the org's current credit balance and billing mode\n(legacy vs credit).","operationId":"getCreditBalance","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Credit balance and billing mode"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/credits/{tenant_id}/checkout":{"post":{"tags":["Billing"],"summary":"Start a credit top-up checkout.","description":"Creates a hosted checkout session to buy credits.","operationId":"createCreditTopupCheckout","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"201":{"description":"Top-up checkout session"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/credits/{tenant_id}/history":{"get":{"tags":["Billing"],"summary":"Get the credit history.","description":"Returns the org's credit ledger entries (grants, purchases, deductions).","operationId":"getCreditHistory","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Credit ledger entries"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/credits/{tenant_id}/razorpay-order":{"post":{"tags":["Billing"],"summary":"Create a Razorpay top-up order.","description":"Razorpay-only path: creates the order the console's Checkout.js\nmodal pays against.","operationId":"createRazorpayTopupOrder","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"201":{"description":"Razorpay order"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/feedback/cancellation":{"post":{"tags":["Billing"],"summary":"Submit cancellation feedback.","description":"Records why an org cancelled; feeds churn analysis. The caller's\ncredential must match the tenant_id in the body.","operationId":"submitCancellationFeedback","requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"200":{"description":"Feedback recorded"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/gdpr/{tenant_id}/consent":{"get":{"tags":["Billing"],"summary":"Get the org's GDPR consent state.","operationId":"getGdprConsent","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Consent state"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Billing"],"summary":"Update the org's GDPR consent.","operationId":"updateGdprConsent","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"200":{"description":"Consent updated"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/gdpr/{tenant_id}/correct":{"post":{"tags":["Billing"],"summary":"Correct the org's billing data (GDPR data-subject correction).","operationId":"gdprCorrect","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"200":{"description":"Billing data corrected"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/gdpr/{tenant_id}/delete":{"post":{"tags":["Billing"],"summary":"Delete the org's billing data (GDPR data-subject deletion).","operationId":"gdprDelete","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Billing data deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/gdpr/{tenant_id}/export":{"post":{"tags":["Billing"],"summary":"Export the org's billing data (GDPR data-subject export).","operationId":"gdprExport","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Billing data export"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/glitch-tracker":{"get":{"tags":["Billing"],"summary":"Get the glitch-tracker status.","description":"Whether the Glitches feed is enabled for the project and its service\nagreement state.","operationId":"getGlitchTrackerStatus","responses":{"200":{"description":"Glitch-tracker status"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/glitch-tracker/disable":{"post":{"tags":["Billing"],"summary":"Disable the glitch-tracker.","operationId":"disableGlitchTracker","responses":{"200":{"description":"Glitch-tracker disabled"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/glitch-tracker/enable":{"post":{"tags":["Billing"],"summary":"Enable the glitch-tracker.","operationId":"enableGlitchTracker","responses":{"200":{"description":"Glitch-tracker enabled"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/infra-agreement/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get the infrastructure agreement.","description":"The org's infrastructure services agreement (the BillingPage's\nagreements tab).","operationId":"getInfraAgreement","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Infrastructure agreement"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/infra-agreement/{tenant_id}/disable":{"post":{"tags":["Billing"],"summary":"Disable the infrastructure agreement.","operationId":"disableInfraAgreement","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Infrastructure agreement disabled"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/invoices/{tenant_id}":{"get":{"tags":["Billing"],"summary":"List the org's invoices.","operationId":"listInvoices","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invoice list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/invoices/{tenant_id}/{invoice_id}/html":{"get":{"tags":["Billing"],"summary":"Render an invoice as HTML.","description":"Returns the printable invoice document for download/email.","operationId":"renderInvoiceHtml","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"invoice_id","in":"path","description":"Invoice id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invoice HTML"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Invoice not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/invoices/{tenant_id}/{invoice_id}/retry":{"post":{"tags":["Billing"],"summary":"Retry a failed invoice payment.","operationId":"retryInvoicePayment","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"invoice_id","in":"path","description":"Invoice id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Payment retried"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Invoice not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/model-tiers":{"get":{"tags":["Billing"],"summary":"List model pricing tiers.","description":"Public — no API key required. The per-tier token prices used for\nusage-based billing.","operationId":"listModelTiers","responses":{"200":{"description":"Model pricing tiers"},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/billing/module-agreement/{tenant_id}/{module}":{"get":{"tags":["Billing"],"summary":"Get a module agreement.","description":"The agreement for one billable module (per-module autodebit setup).","operationId":"getModuleAgreement","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"module","in":"path","description":"Module id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Module agreement"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Module agreement not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/module-agreement/{tenant_id}/{module}/autodebit":{"post":{"tags":["Billing"],"summary":"Set up module autodebit.","description":"Authorizes automatic debit for the module's usage charges.","operationId":"setupModuleAutodebit","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"module","in":"path","description":"Module id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Autodebit set up"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/module-agreement/{tenant_id}/{module}/disable":{"post":{"tags":["Billing"],"summary":"Disable a module agreement.","operationId":"disableModuleAgreement","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"module","in":"path","description":"Module id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Module agreement disabled"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/overage/{tenant_id}":{"post":{"tags":["Billing"],"summary":"Toggle overage billing.","description":"Enables or disables allow-overage (continue serving past the credit\nbalance and bill the difference) for the org.","operationId":"toggleOverage","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"200":{"description":"Overage setting updated"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/overview/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get the billing overview.","description":"The BillingPage's landing view: current plan, subscription status,\nbalance, and spend summary in one response.","operationId":"getBillingOverview","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Billing overview"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/payment-methods/{tenant_id}":{"get":{"tags":["Billing"],"summary":"List the org's payment methods.","operationId":"listPaymentMethods","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Payment methods"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/payment-methods/{tenant_id}/razorpay-authorization":{"post":{"tags":["Billing"],"summary":"Authorize a Razorpay payment method.","description":"Starts the Razorpay authorization flow for adding a card via the\nconsole's in-page Checkout.js modal.","operationId":"createRazorpayPaymentMethodAuthorization","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Authorization session (razorpay_key_id + order id)"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/payment-methods/{tenant_id}/{pm_id}":{"delete":{"tags":["Billing"],"summary":"Remove a payment method.","operationId":"removePaymentMethod","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"pm_id","in":"path","description":"Payment method id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Payment method removed"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Payment method not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/payment-methods/{tenant_id}/{pm_id}/default":{"post":{"tags":["Billing"],"summary":"Set the default payment method.","operationId":"setDefaultPaymentMethod","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"pm_id","in":"path","description":"Payment method id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Default payment method set"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Payment method not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/plans":{"get":{"tags":["Billing"],"summary":"List the billing plans (the pricing page's source).","description":"Public — no API key required. Returns every active plan with its\nprices, limits, support tier, SLA, and features.","operationId":"listPlans","responses":{"200":{"description":"Active plans","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPlanList"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/billing/plans/{plan_id}":{"get":{"tags":["Billing"],"summary":"Get one plan's detail.","description":"Public — no API key required.","operationId":"getPlanDetail","parameters":[{"name":"plan_id","in":"path","description":"Plan id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Plan detail"},"404":{"description":"Plan not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/billing/portal":{"post":{"tags":["Billing"],"summary":"Open the billing portal.","description":"Creates a provider customer-portal session for self-serve payment\nmethod and subscription management.","operationId":"createPortal","requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"201":{"description":"Portal session created (url in the body)"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/pricing":{"get":{"tags":["Billing"],"summary":"Public pricing matrix.","description":"Public — no API key required. The per-plan, per-provider price list\nthe pricing page renders.","operationId":"publicPricing","responses":{"200":{"description":"Public pricing matrix"},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/billing/service-agreement/{tenant_id}/{service_id}/agree":{"post":{"tags":["Billing"],"summary":"Agree to a service agreement.","description":"Records the org's acceptance of one service's agreement (enables the\nservice for billing).","operationId":"agreeService","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"service_id","in":"path","description":"Service id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Service agreement accepted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/service-agreement/{tenant_id}/{service_id}/disable":{"post":{"tags":["Billing"],"summary":"Disable a service agreement.","operationId":"disableServiceAgreement","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}},{"name":"service_id","in":"path","description":"Service id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Service agreement disabled"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/services":{"get":{"tags":["Billing"],"summary":"List billable services.","description":"Public — no API key required. The service catalog the console's\nBillingPage enables per org.","operationId":"listBillingServices","responses":{"200":{"description":"Billable services"},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/billing/services/{tenant_id}":{"get":{"tags":["Billing"],"summary":"List the org's enabled services.","operationId":"listTenantServices","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Services enabled for the org"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/setup/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Complete the org's billing setup.","description":"Bootstraps the org's billing customer record (free tier) with the\nsignup email; idempotent.","operationId":"setupTenantBilling","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Billing setup complete"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/spending-cap/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get the spending cap.","operationId":"getSpendingCap","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current spending cap"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Billing"],"summary":"Set the spending cap.","description":"Accepts PUT, PATCH and POST on the same path; the body is the cap\nconfiguration.","operationId":"setSpendingCap","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpendingCapRequest"}}},"required":true},"responses":{"200":{"description":"Spending cap set"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Billing"],"summary":"Delete the spending cap.","operationId":"deleteSpendingCap","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Spending cap removed"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/subscription/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get the org's subscription.","description":"Returns the current subscription with the display amount in the org's\npinned currency, `is_paid`, and any scheduled (pending) plan change.","operationId":"getSubscription","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current subscription"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/subscription/{tenant_id}/cancel":{"post":{"tags":["Billing"],"summary":"Cancel the subscription.","description":"Cancels at the current period end (the console confirms first).","operationId":"cancelSubscription","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Subscription cancelled"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/subscription/{tenant_id}/change":{"post":{"tags":["Billing"],"summary":"Change the plan (in-place upgrade/downgrade).","operationId":"changePlan","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePlanRequest"}}},"required":true},"responses":{"200":{"description":"Plan changed (or downgrade scheduled)"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/subscription/{tenant_id}/reactivate":{"post":{"tags":["Billing"],"summary":"Reactivate a cancelled subscription.","operationId":"reactivateSubscription","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Subscription reactivated"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/tax-info/{tenant_id}":{"get":{"tags":["Billing"],"summary":"Get the org's tax info.","operationId":"getTaxInfo","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tax info (GST/VAT registration)"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Billing"],"summary":"Update the org's tax info.","operationId":"updateTaxInfo","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxInfoRequest"}}},"required":true},"responses":{"200":{"description":"Tax info updated"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/tax/calculate":{"post":{"tags":["Billing"],"summary":"Calculate tax for a charge.","description":"Applies the org's tax-info settings (GST/VAT, reverse charge, LUT,\nexemption) to a pre-tax amount. The stored tax profile fills\nomitted body fields only for a caller authenticated as that\ntenant; an unauthenticated caller gets the pure computation from\nthe body fields.","operationId":"calculateTax","requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"200":{"description":"Tax breakdown for the amount"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/usage/{tenant_id}/by-model":{"get":{"tags":["Billing"],"summary":"Get usage by model.","description":"Token usage and cost broken down per AI model.","operationId":"getUsageByModel","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Usage by model"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/usage/{tenant_id}/forecast":{"get":{"tags":["Billing"],"summary":"Get the usage forecast.","description":"Projected end-of-period spend based on usage so far.","operationId":"getUsageForecast","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Projected end-of-period spend"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/usage/{tenant_id}/history":{"get":{"tags":["Billing"],"summary":"Get the usage history.","description":"Period-by-period usage history (the BillingPage's usage table).","operationId":"getUsageHistory","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Usage history"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/usage/{tenant_id}/overage":{"get":{"tags":["Billing"],"summary":"Get the current overage amount.","operationId":"getUsageOverage","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current overage"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/usage/{tenant_id}/spread":{"get":{"tags":["Billing"],"summary":"Get the usage spread.","description":"Returns usage distributed across the billing period (the spend-over-\ntime chart).","operationId":"getUsageSpread","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Usage spread across the period"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/billing/usage/{tenant_id}/summary":{"get":{"tags":["Billing"],"summary":"Get the usage summary.","description":"Aggregated usage-and-spend summary for the current period.","operationId":"getBillingUsageSummary","parameters":[{"name":"tenant_id","in":"path","description":"Tenant id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Usage summary"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Not your org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/build":{"get":{"tags":["Build"],"summary":"List builds.","description":"Returns the builds for the caller's project.","operationId":"listBuilds","responses":{"200":{"description":"Build list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Build"],"summary":"Start a build.","description":"Starts a container image build and returns the build record.\n\nFor a private repository, either install the Scalix GitHub App for the\nproject (builds then authenticate themselves) or pass `auth_token`.","operationId":"createBuild","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuildCreateRequest"}}},"required":true},"responses":{"200":{"description":"Build started"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/build/upload":{"post":{"tags":["Build"],"summary":"Upload source and build.","description":"Builds from an uploaded source tree instead of a URL, so the source never\nhas to be reachable from the internet. The request body IS the gzipped\ntarball (`Content-Type: application/gzip`); metadata goes in the query\nstring. Multipart is not accepted.","operationId":"uploadBuild","parameters":[{"name":"image_tag","in":"query","description":"Tag for the resulting image. Auto-generated if omitted.","required":false,"schema":{"type":"string"}},{"name":"dockerfile_path","in":"query","description":"Path to the Dockerfile within the uploaded tree. Auto-detected if omitted.","required":false,"schema":{"type":"string"}},{"name":"build_args","in":"query","description":"Build-time ARGs as a url-encoded JSON object, e.g. {\"VITE_API_URL\":\"https://api.example.com\"}","required":false,"schema":{"type":"string"}},{"name":"timeout_seconds","in":"query","description":"Build timeout in seconds. Default 600, maximum 3600.","required":false,"schema":{"type":"integer","format":"int32"}}],"requestBody":{"description":"Gzipped tarball of the source tree","content":{"application/gzip":{"schema":{"type":"string"}}},"required":true},"responses":{"201":{"description":"Build started"},"400":{"description":"Body is empty, not a gzipped tarball, too large, or build_args is malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/build/{id}":{"get":{"tags":["Build"],"summary":"Get a build.","description":"Returns a single build by id.","operationId":"getBuild","parameters":[{"name":"id","in":"path","description":"Build id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Build details"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/build/{id}/cancel":{"post":{"tags":["Build"],"summary":"Cancel a build.","description":"Cancels an in-progress build.","operationId":"cancelBuild","parameters":[{"name":"id","in":"path","description":"Build id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Build cancelled"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/build/{id}/logs":{"get":{"tags":["Build"],"summary":"Get build logs.","description":"Returns log output for a build.","operationId":"getBuildLogs","parameters":[{"name":"id","in":"path","description":"Build id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Build logs"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compliance/audit":{"get":{"tags":["Compliance"],"summary":"Query the audit log.","description":"Returns audit events for the caller's tenant, filterable by action and time\nrange. The tenant scope is always taken from the token, never the query.","operationId":"queryAuditLog","parameters":[{"name":"action","in":"query","description":"Filter by audit action (e.g. auth_login, data_access)","required":false,"schema":{"type":"string"}},{"name":"from","in":"query","description":"Start of time range (RFC 3339)","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","description":"End of time range (RFC 3339)","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max number of events to return","required":false,"schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"Audit events for the caller's tenant","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntry"}}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the compliance:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compliance/audit/export":{"get":{"tags":["Compliance"],"summary":"Export the audit log.","description":"Returns the full audit trail for the caller's tenant for compliance export\n(JSON by default, CSV with `?format=csv`).","operationId":"exportAuditLog","responses":{"200":{"description":"Full audit trail export for the caller's tenant","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntry"}}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the compliance:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compliance/gdpr/requests":{"get":{"tags":["Compliance"],"summary":"List GDPR requests.","description":"Returns the data-subject requests for the caller's tenant.","operationId":"listGdprRequests","responses":{"200":{"description":"Data-subject requests for the caller's tenant","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DataSubjectRequest"}}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the compliance:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Compliance"],"summary":"Create a GDPR request.","description":"Files a GDPR data-subject request (access / erasure / rectification). This is\nintake only: the request is persisted with status `pending`; export and\nerasure are fulfilled out of band.","operationId":"createGdprRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGdprRequest"}}},"required":true},"responses":{"201":{"description":"Data-subject request created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataSubjectRequest"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the compliance:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compliance/gdpr/requests/{id}":{"get":{"tags":["Compliance"],"summary":"Get a GDPR request.","description":"Returns a single GDPR data-subject request by id.","operationId":"getGdprRequest","parameters":[{"name":"id","in":"path","description":"Data-subject request id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The data-subject request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataSubjectRequest"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the compliance:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"GDPR request not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compliance/gdpr/requests/{id}/status":{"post":{"tags":["Compliance"],"summary":"Advance a GDPR data-subject request through its lifecycle.","description":"SEC-1: the DSR flow was intake-only — requests sat `pending` forever with no\nway to fulfill them, while the compliance status implied a working workflow.\nA data-protection officer (compliance:write) now moves each request through\npending → in_progress → completed/rejected; terminal states stamp\n`completed_at`, giving an auditable fulfillment record within the GDPR Art.\n12(3) one-month window. Tenant-scoped.","operationId":"updateGdprRequestStatus","parameters":[{"name":"id","in":"path","description":"Data-subject request id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateGdprStatusBody"}}},"required":true},"responses":{"200":{"description":"Updated data-subject request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataSubjectRequest"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the compliance:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"GDPR request not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compliance/status":{"get":{"tags":["Compliance"],"summary":"Get compliance status.","description":"Runs the compliance checks (encryption, audit, access controls) and returns\neach check's result plus an overall score.","operationId":"getComplianceStatus","responses":{"200":{"description":"Compliance checks and overall score","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceStatus"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the compliance:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compute/deployments":{"get":{"tags":["Compute"],"summary":"List deployments.","description":"Returns all compute deployments for the caller's project.","operationId":"listDeployments","responses":{"200":{"description":"Deployment list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Compute"],"summary":"Create a deployment.","description":"Deploys a container/VM compute workload and returns the created deployment.","operationId":"createDeployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputeDeployRequest"}}},"required":true},"responses":{"201":{"description":"Deployment created"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compute/deployments/{id}":{"get":{"tags":["Compute"],"summary":"Get a deployment.","description":"Returns a single compute deployment by id.","operationId":"getDeployment","parameters":[{"name":"id","in":"path","description":"Deployment id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deployment details"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Compute"],"summary":"Delete a deployment.","description":"Removes a compute deployment by id.","operationId":"deleteDeployment","parameters":[{"name":"id","in":"path","description":"Deployment id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deployment deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compute/deployments/{id}/instances":{"get":{"tags":["Compute"],"summary":"List deployment instances.","description":"Returns the running instances of a compute deployment.","operationId":"listDeploymentInstances","parameters":[{"name":"id","in":"path","description":"Deployment id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Instance list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compute/deployments/{id}/logs":{"get":{"tags":["Compute"],"summary":"Get deployment logs.","description":"Returns log output for a compute deployment.","operationId":"getDeploymentLogs","parameters":[{"name":"id","in":"path","description":"Deployment id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Log output"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compute/deployments/{id}/restart":{"post":{"tags":["Compute"],"summary":"Restart a deployment.","description":"Restarts all instances of a compute deployment.","operationId":"restartDeployment","parameters":[{"name":"id","in":"path","description":"Deployment id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deployment restarted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compute/deployments/{id}/rollback":{"post":{"tags":["Compute"],"summary":"Roll back a deployment.","description":"Rolls a compute deployment back to a previous version.","operationId":"rollbackDeployment","parameters":[{"name":"id","in":"path","description":"Deployment id","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Rollback request (target version)","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Deployment rolled back"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compute/deployments/{id}/scale":{"post":{"tags":["Compute"],"summary":"Scale a deployment.","description":"Adjusts the instance count (min/max) for a compute deployment.","operationId":"scaleDeployment","parameters":[{"name":"id","in":"path","description":"Deployment id","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Scale request (min/max instances)","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Deployment scaled"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/compute/deployments/{id}/versions":{"get":{"tags":["Compute"],"summary":"List deployment versions.","description":"Returns the version history of a compute deployment.","operationId":"listDeploymentVersions","parameters":[{"name":"id","in":"path","description":"Deployment id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deployment versions"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/computers":{"get":{"tags":["Computers"],"summary":"List your Computers.","operationId":"computerList","responses":{"200":{"description":"Your Computers, newest first","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ComputerInfo"}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Computers"],"summary":"Create a Computer.","description":"Boots a persistent Linux machine and returns once it is provisioning. The\nroot disk survives stop/start and is only reclaimed by DELETE. Billed per\nstart, per vCPU-hour and GB-hour while running, and per GB-month of disk\nfor as long as the Computer exists.","operationId":"computerCreate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerCreateRequest"}}},"required":true},"responses":{"201":{"description":"Computer created (initially CREATING)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerInfo"}}}},"400":{"description":"Invalid name or resource shape","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Credit exhausted or plan limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"A Computer with that name already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"No host has capacity for the requested resources","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/computers/by-name/{name}":{"put":{"tags":["Computers"],"summary":"Get or create a Computer by name.","description":"Idempotent: the first call creates the machine (201), every identical\nrepeat returns the existing one (200). Resource changes on a repeat are\nignored — the existing machine wins. Use this instead of create when an\nagent may retry.","operationId":"computerGetOrCreateByName","parameters":[{"name":"name","in":"path","description":"Lowercase DNS label, max 63 characters","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerCreateRequest"}}},"required":true},"responses":{"200":{"description":"The existing Computer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerInfo"}}}},"201":{"description":"Computer created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerInfo"}}}},"400":{"description":"Invalid name or resource shape","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"No host has capacity for the requested resources","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/computers/{id}":{"get":{"tags":["Computers"],"summary":"Get one Computer.","operationId":"computerGet","parameters":[{"name":"id","in":"path","description":"Computer id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The Computer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerInfo"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Computers"],"summary":"Delete a Computer.","description":"The only operation that reclaims the root disk. Irreversible — stop the\nComputer instead if you want the files back later.","operationId":"computerDelete","parameters":[{"name":"id","in":"path","description":"Computer id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Computer and its disk deleted"},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/computers/{id}/exec":{"post":{"tags":["Computers"],"summary":"Run a command inside a Computer.","operationId":"computerExec","parameters":[{"name":"id","in":"path","description":"Computer id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerExecRequest"}}},"required":true},"responses":{"200":{"description":"Command finished","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerExecResult"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The Computer is not RUNNING","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/computers/{id}/files":{"get":{"tags":["Computers"],"summary":"Read one file out of a Computer.","operationId":"computerReadFile","parameters":[{"name":"id","in":"path","description":"Computer id","required":true,"schema":{"type":"string"}},{"name":"path","in":"query","description":"Absolute path inside the guest","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File contents, base64-encoded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerFileRead"}}}},"400":{"description":"Missing `path` query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The Computer is not RUNNING","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Computers"],"summary":"Write files into a Computer.","operationId":"computerWriteFiles","parameters":[{"name":"id","in":"path","description":"Computer id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerWriteFilesRequest"}}},"required":true},"responses":{"204":{"description":"Files written"},"400":{"description":"No files, or more than 64","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The Computer is not RUNNING","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/computers/{id}/ssh-keys":{"put":{"tags":["Computers"],"summary":"Replace a Computer's authorised ssh keys.","description":"Sends the whole list every time, so removing a key is the same operation as\nadding one. On a RUNNING machine the change applies immediately — a\nrevoked key stops working now, not at the next restart. On a stopped\nmachine it is stored and delivered when it next boots.","operationId":"computerSetSshKeys","parameters":[{"name":"id","in":"path","description":"Computer id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerSshKeysRequest"}}},"required":true},"responses":{"200":{"description":"The Computer, with the new key list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerInfo"}}}},"400":{"description":"Not an OpenSSH public key, or more than 32","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The keys could not be delivered to the running machine","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/computers/{id}/start":{"post":{"tags":["Computers"],"summary":"Start a stopped Computer.","description":"Boots the same disk on the same host and reclaims the same address.","operationId":"computerStart","parameters":[{"name":"id","in":"path","description":"Computer id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The Computer, now RUNNING","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerInfo"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"The Computer's host is unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/computers/{id}/stop":{"post":{"tags":["Computers"],"summary":"Stop a Computer.","description":"Halts the machine. The root disk and the network address are kept, so a\nlater start comes back to the same files at the same address. Runtime\nbilling stops; disk billing continues at the parked rate.","operationId":"computerStop","parameters":[{"name":"id","in":"path","description":"Computer id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The Computer, now STOPPED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComputerInfo"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/cron/schedules":{"get":{"tags":["Cron"],"summary":"List cron schedules.","description":"Returns all scheduled jobs for the caller's project.","operationId":"listCronSchedules","responses":{"200":{"description":"Schedule list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Cron"],"summary":"Create a cron schedule.","description":"Creates a new scheduled job.","operationId":"createCronSchedule","requestBody":{"description":"Create-schedule request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"201":{"description":"Schedule created"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/cron/schedules/{id}":{"get":{"tags":["Cron"],"summary":"Get a cron schedule.","description":"Returns a single scheduled job by id.","operationId":"getCronSchedule","parameters":[{"name":"id","in":"path","description":"Schedule id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Schedule details"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Cron"],"summary":"Update a cron schedule.","description":"Updates an existing scheduled job.","operationId":"updateCronSchedule","parameters":[{"name":"id","in":"path","description":"Schedule id","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Update-schedule request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Schedule updated"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Cron"],"summary":"Delete a cron schedule.","description":"Removes a scheduled job by id.","operationId":"deleteCronSchedule","parameters":[{"name":"id","in":"path","description":"Schedule id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Schedule deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/cron/schedules/{id}/executions":{"get":{"tags":["Cron"],"summary":"List schedule executions.","description":"Returns the execution history of a scheduled job.","operationId":"listCronExecutions","parameters":[{"name":"id","in":"path","description":"Schedule id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Execution history"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/cron/schedules/{id}/trigger":{"post":{"tags":["Cron"],"summary":"Trigger a cron schedule.","description":"Runs a scheduled job immediately, outside its normal schedule.","operationId":"triggerCronSchedule","parameters":[{"name":"id","in":"path","description":"Schedule id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Schedule triggered"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/databases":{"get":{"tags":["Database"],"summary":"List databases.","description":"Lists the project's databases. `include_deleted=true` also returns\nsoft-deleted databases still inside the recovery grace window.","operationId":"listDatabases","parameters":[{"name":"include_deleted","in":"query","description":"Also return soft-deleted databases restorable within the grace window","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Databases in the project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDatabasesResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Database"],"summary":"Create a database.","description":"Creates a ScalixNova database in the project on the requested PostgreSQL\nmajor version (16 default, 17, or 18). The version is fixed at creation;\nbranches and point-in-time restores keep it.","operationId":"createDatabase","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDatabaseRequest"}}},"required":true},"responses":{"201":{"description":"Database created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDatabaseResponse"}}}},"400":{"description":"Invalid name, isolation, or pg_version (message lists the supported versions)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"A database with this name already exists in the org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"501":{"description":"Dedicated tier not provisionable on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/databases/provision":{"post":{"tags":["Database"],"summary":"Get or create the project's default database.","description":"Idempotent: returns the project's default database connection info,\ncreating the database (on the default PostgreSQL version) if none exists.","operationId":"provisionDatabase","responses":{"200":{"description":"Connection info for the project's default database"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/databases/{id}":{"get":{"tags":["Database"],"summary":"Get a database.","description":"Fetches one database by id, including its PostgreSQL version and isolation tier.","operationId":"getDatabase","parameters":[{"name":"id","in":"path","description":"Database id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseJson"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Database not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Database"],"summary":"Delete a database.","description":"Soft-deletes the database: it is hidden from listings and restorable via\n`POST /v1/databases/{id}/restore` until the grace window ends, after which\nit is purged permanently.","operationId":"deleteDatabase","parameters":[{"name":"id","in":"path","description":"Database id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Database scheduled for deletion"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Database not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/databases/{id}/restore":{"post":{"tags":["Database"],"summary":"Restore a soft-deleted database.","description":"Undoes a delete within the recovery grace window; the database returns to\n`active` with its data, version, and tier intact.","operationId":"restoreDatabase","parameters":[{"name":"id","in":"path","description":"Database id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Database restored to active"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Database not found or past the grace window","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/domains":{"get":{"tags":["Domains"],"summary":"List custom domains.","description":"Returns all custom domains attached to the caller's project, with their\nverification and SSL status.","operationId":"listDomains","responses":{"200":{"description":"All custom domains for the caller's project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDomainsResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Domains"],"summary":"Add a custom domain.","description":"Registers a custom domain for the caller's project and returns the created\nrecord plus the DNS records (CNAME + TXT) needed to verify and serve it.","operationId":"addDomain","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddDomainBody"}}},"required":true},"responses":{"201":{"description":"Domain registered; returns DNS setup instructions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddDomainResponse"}}}},"400":{"description":"Invalid or platform-reserved domain","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Domain already registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/domains/{id}":{"get":{"tags":["Domains"],"summary":"Get a custom domain.","description":"Returns a single custom domain by id, scoped to the caller's project.","operationId":"getDomain","parameters":[{"name":"id","in":"path","description":"Domain id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The domain","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainJson"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Domains"],"summary":"Remove a custom domain.","description":"Detaches a custom domain from the caller's project and deletes its record.","operationId":"deleteDomain","parameters":[{"name":"id","in":"path","description":"Domain id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Domain removed"},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/domains/{id}/ssl":{"post":{"tags":["Domains"],"summary":"Provision SSL for a domain.","description":"Starts background Let's Encrypt certificate issuance for a verified domain.\nThe domain must be active; automatic SSL must be configured on the deployment.","operationId":"provisionDomainSsl","parameters":[{"name":"id","in":"path","description":"Domain id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"SSL provisioning started","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionSslResponse"}}}},"400":{"description":"Domain not verified yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"501":{"description":"Automatic SSL not configured on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/domains/{id}/verify":{"post":{"tags":["Domains"],"summary":"Verify a custom domain.","description":"Confirms — via a standard public DNS lookup, no provider credentials — that the\ncustomer's domain points at our edge (its A records match `cname.<platform>`,\nor a configured `SCALIX_EDGE_IP`). On success, marks the domain active. This is\nthe industry-standard \"does it point at us\" check (Vercel/Netlify/Render).","operationId":"verifyDomain","parameters":[{"name":"id","in":"path","description":"Domain id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"DNS verification result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyDomainResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"DNS lookup failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/analytics/campaign/{template_name}":{"get":{"tags":["Email"],"summary":"Get campaign analytics.","description":"Returns engagement metrics for a single template. Requires the `email:read`\nscope.","operationId":"getEmailCampaignAnalytics","parameters":[{"name":"template_name","in":"path","description":"Template to report on","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Campaign analytics"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/analytics/summary":{"get":{"tags":["Email"],"summary":"Get analytics summary.","description":"Returns aggregate open, click, bounce, and complaint rates for the org.\nRequires the `email:read` scope.","operationId":"getEmailAnalyticsSummary","responses":{"200":{"description":"Analytics summary"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/domains":{"get":{"tags":["Email"],"summary":"List sending domains.","description":"Returns the org's bring-your-own sending domains and their verification\nstate. Requires the `email:read` scope.","operationId":"listEmailDomains","responses":{"200":{"description":"Sending domains"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Email"],"summary":"Add a sending domain.","description":"Registers a domain and returns the DNS records required to verify it.\nRequires the `email:send` scope.","operationId":"addEmailDomain","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailAddDomainRequest"}}},"required":true},"responses":{"200":{"description":"Domain added","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailDomain"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:send scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Domain already registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/domains/{id}":{"delete":{"tags":["Email"],"summary":"Delete a sending domain.","description":"Removes a sending domain from the org. Requires the `email:send` scope.","operationId":"deleteEmailDomain","parameters":[{"name":"id","in":"path","description":"Domain id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Domain deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:send scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/domains/{id}/verify":{"post":{"tags":["Email"],"summary":"Verify a sending domain.","description":"Re-checks the domain's DNS records and updates its verification state.\nVerifying a domain proves ownership; it does not by itself enable delivery.\nRequires the `email:send` scope.","operationId":"verifyEmailDomain","parameters":[{"name":"id","in":"path","description":"Domain id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verification result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailDomain"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:send scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/events":{"get":{"tags":["Email"],"summary":"List delivery events.","description":"Returns recent per-message delivery events (delivered, bounced, opened,\nclicked). Requires the `email:read` scope.","operationId":"listEmailEvents","responses":{"200":{"description":"Delivery events"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/send/raw":{"post":{"tags":["Email"],"summary":"Send a raw email.","description":"Sends an HTML email without a stored template. Requires the `email:send`\nscope.","operationId":"sendRawEmail","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSendRawRequest"}}},"required":true},"responses":{"200":{"description":"Email accepted for delivery","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSendResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:send scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Bring-your-own delivery is not enabled for this org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/send/tx":{"post":{"tags":["Email"],"summary":"Send a templated email.","description":"Renders `template` with `data` and sends it to `to`. Requires the\n`email:send` scope.","operationId":"sendTransactionalEmail","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSendTxRequest"}}},"required":true},"responses":{"200":{"description":"Email accepted for delivery","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailSendResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:send scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Bring-your-own delivery is not enabled for this org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/settings":{"get":{"tags":["Email"],"summary":"Get email settings.","description":"Returns the org's sender identity and delivery configuration, including\nwhether bring-your-own delivery is enabled. Requires the `email:read` scope.","operationId":"getEmailSettings","responses":{"200":{"description":"Email settings"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Email"],"summary":"Update email settings.","description":"Updates the org's sender identity and delivery configuration. Requires the\n`email:send` scope.","operationId":"updateEmailSettings","requestBody":{"description":"Settings to apply","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Settings updated"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:send scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/stats":{"get":{"tags":["Email"],"summary":"Get email stats.","description":"Returns send counts and delivery health for the org. Requires the\n`email:read` scope.","operationId":"getEmailStats","responses":{"200":{"description":"Email stats"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/suppression":{"get":{"tags":["Email"],"summary":"List suppressed addresses.","description":"Returns addresses excluded from sending after a hard bounce or complaint.\nRequires the `email:read` scope.","operationId":"listEmailSuppression","responses":{"200":{"description":"Suppression list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/templates":{"get":{"tags":["Email"],"summary":"List email templates.","description":"Returns the org's stored templates. Requires the `email:read` scope.","operationId":"listEmailTemplates","responses":{"200":{"description":"Templates"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Email"],"summary":"Create an email template.","description":"Stores a new template for the org. Requires the `email:write` scope.","operationId":"createEmailTemplate","requestBody":{"description":"Template definition","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Template created"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/email/templates/{id}":{"put":{"tags":["Email"],"summary":"Update an email template.","description":"Replaces a stored template. Requires the `email:write` scope.","operationId":"updateEmailTemplate","parameters":[{"name":"id","in":"path","description":"Template id","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Template definition","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Template updated"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Email"],"summary":"Delete an email template.","description":"Removes a stored template. Requires the `email:write` scope.","operationId":"deleteEmailTemplate","parameters":[{"name":"id","in":"path","description":"Template id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Template deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing email:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/env":{"get":{"tags":["Environment"],"summary":"List environment variables.","description":"Returns all project-level environment variables (secret values masked).","operationId":"listEnvVars","responses":{"200":{"description":"All project environment variables","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListEnvResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Environment"],"summary":"Set an environment variable.","description":"Creates or updates a single project-level environment variable.","operationId":"setEnvVar","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetEnvBody"}}},"required":true},"responses":{"200":{"description":"Variable created or updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvVar"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/env/bulk":{"post":{"tags":["Environment"],"summary":"Bulk-import environment variables.","description":"Imports many project-level environment variables in one request.","operationId":"bulkImportEnvVars","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkImportBody"}}},"required":true},"responses":{"200":{"description":"Variables imported","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListEnvResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/env/{id}":{"delete":{"tags":["Environment"],"summary":"Delete an environment variable.","description":"Removes a project-level environment variable by id.","operationId":"deleteEnvVar","parameters":[{"name":"id","in":"path","description":"Environment variable id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Variable deleted","content":{"application/json":{"schema":{}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Variable not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/events/subscriptions/{id}":{"get":{"tags":["Events"],"summary":"Get a subscription.","description":"Returns a single event subscription by id.","operationId":"getEventSubscription","parameters":[{"name":"id","in":"path","description":"Subscription id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Subscription details"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Events"],"summary":"Delete a subscription.","description":"Removes an event subscription by id.","operationId":"deleteEventSubscription","parameters":[{"name":"id","in":"path","description":"Subscription id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Subscription deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/events/subscriptions/{id}/deliveries":{"get":{"tags":["Events"],"summary":"List subscription deliveries.","description":"Returns the delivery attempts for an event subscription.","operationId":"listSubscriptionDeliveries","parameters":[{"name":"id","in":"path","description":"Subscription id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Delivery attempts"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/events/topics":{"get":{"tags":["Events"],"summary":"List topics.","description":"Returns all event-bus topics for the caller's project.","operationId":"listEventTopics","responses":{"200":{"description":"Topic list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Events"],"summary":"Create a topic.","description":"Creates a new event-bus topic.","operationId":"createEventTopic","responses":{"201":{"description":"Topic created"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/events/topics/{id}":{"get":{"tags":["Events"],"summary":"Get a topic.","description":"Returns a single event-bus topic by id or name.","operationId":"getEventTopic","parameters":[{"name":"id","in":"path","description":"Topic id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Topic details"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Events"],"summary":"Delete a topic.","description":"Removes an event-bus topic by id or name.","operationId":"deleteEventTopic","parameters":[{"name":"id","in":"path","description":"Topic id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Topic deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/events/topics/{id}/events":{"get":{"tags":["Events"],"summary":"List events on a topic.","description":"Returns the recent events published to a topic.","operationId":"listTopicEvents","parameters":[{"name":"id","in":"path","description":"Topic id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Events on the topic"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/events/topics/{id}/publish":{"post":{"tags":["Events"],"summary":"Publish an event.","description":"Publishes an event payload to a topic.","operationId":"publishEvent","parameters":[{"name":"id","in":"path","description":"Topic id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Event payload","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Event published"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/events/topics/{id}/subscriptions":{"get":{"tags":["Events"],"summary":"List a topic's subscriptions.","description":"Returns the subscriptions attached to a topic.","operationId":"listTopicSubscriptions","parameters":[{"name":"id","in":"path","description":"Topic id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Subscription list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Events"],"summary":"Create a subscription.","description":"Creates a subscription that delivers a topic's events to an endpoint.","operationId":"createEventSubscription","parameters":[{"name":"id","in":"path","description":"Topic id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Subscription request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"201":{"description":"Subscription created"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/functions":{"get":{"tags":["Functions"],"summary":"List functions.","description":"Returns all serverless functions for the caller's project.","operationId":"listFunctions","responses":{"200":{"description":"Function list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Functions"],"summary":"Create a function.","description":"Deploys a serverless function and returns the created function.","operationId":"createFunction","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionDeployRequest"}}},"required":true},"responses":{"201":{"description":"Function created"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/functions/{id}":{"get":{"tags":["Functions"],"summary":"Get a function.","description":"Returns a single serverless function by id or name.","operationId":"getFunction","parameters":[{"name":"id","in":"path","description":"Function id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Function details"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Functions"],"summary":"Update a function.","description":"Redeploys a serverless function with a new configuration.","operationId":"updateFunction","parameters":[{"name":"id","in":"path","description":"Function id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FunctionDeployRequest"}}},"required":true},"responses":{"200":{"description":"Function updated"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Functions"],"summary":"Delete a function.","description":"Removes a serverless function by id or name.","operationId":"deleteFunction","parameters":[{"name":"id","in":"path","description":"Function id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Function deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/functions/{id}/invocations":{"get":{"tags":["Functions"],"summary":"List function invocations.","description":"Returns the invocation history for a serverless function.","operationId":"listFunctionInvocations","parameters":[{"name":"id","in":"path","description":"Function id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invocation history"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/functions/{id}/invoke":{"post":{"tags":["Functions"],"summary":"Invoke a function.","description":"Invokes a serverless function with the supplied payload and returns its result.","operationId":"invokeFunction","parameters":[{"name":"id","in":"path","description":"Function id or name","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Invocation payload","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Invocation result"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/functions/{id}/logs":{"get":{"tags":["Functions"],"summary":"Get function logs.","description":"Returns log output for a serverless function.","operationId":"getFunctionLogs","parameters":[{"name":"id","in":"path","description":"Function id or name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Function logs"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/glitches":{"get":{"tags":["Glitches"],"summary":"Project glitch summary.","description":"Aggregated tenant-side edge faults in the window, sorted by frequency:\ngroup class, key, counts, first/last seen, and a bounded sample of real\npaths. The default classes are the platform's starting point — the\ntenant's own rules (see the glitch rules endpoints) override them per\nproject, and `custom` groups carry the tenant's own labels.\n\nServed only once the org enables Glitch Tracker (free base,\n7-day retention) or Glitch Tracker Plus (2026-10-07): orgs\nthat have not opted in receive an empty feed.\n\nRequires the `glitches:read` scope and a project-scoped credential.","operationId":"getGlitchSummary","parameters":[{"name":"window_days","in":"query","description":"Look-back window in days (1-30, default 7)","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Project glitch summary"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the glitches:read scope or is not project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/glitches/events":{"get":{"tags":["Glitches"],"summary":"List project glitch events.","description":"Recent glitch events for the caller's project, newest first — metadata\nonly (status, route, host, class). Events recorded under a tenant-defined\nrule appear with class `custom` and the tenant's own label as the group\nkey.\n\nServed only once the org enables Glitch Tracker (free\nbase, 7-day retention) or Glitch Tracker Plus\n(2026-10-07): orgs that have not opted in receive an\nempty list.\n\nRequires the `glitches:read` scope and a project-scoped credential.","operationId":"listGlitchEvents","parameters":[{"name":"limit","in":"query","description":"Max events to return (1-200, default 50)","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"List project glitch events"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the glitches:read scope or is not project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/glitches/rules":{"get":{"tags":["Glitches"],"summary":"List this project's glitch rules.","description":"The tenant owns the definition of \"glitch\" (2026-10-05): rules are\nevaluated at the edge record sites BEFORE the platform's default\nclassification. First matching rule (creation order) wins — `ignore`\nsuppresses the observation entirely, `track` records it under the\ntenant's own label even for statuses the platform does not classify by\ndefault. Rules apply within a minute.\n\nRequires the `glitches:read` scope and a project-scoped credential.","operationId":"listGlitchRules","responses":{"200":{"description":"Tenant-defined glitch rules for this project, in evaluation order"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the glitches:read scope or is not project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Glitches"],"summary":"Create one glitch rule for this project.","description":"The tenant decides what counts as a glitch for their own app. `action:\n\"ignore\"` suppresses matching observations; `action: \"track\"` records\nthem under `label` (the tenant's own category name, which becomes the\ngroup key, class `custom`) with an optional tenant-authored remediation\n`hint`. At most 50 rules per project; at most 32 statuses per rule;\n`path_prefix` must start with `/`; `host` is a bare hostname. Rules\napply within a minute, and only affect FUTURE observations.\n\nRequires the `glitches:write` scope and a project-scoped credential.","operationId":"createGlitchRule","requestBody":{"description":"The rule to create","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GlitchRuleCreate"}}},"required":true},"responses":{"201":{"description":"Rule created"},"400":{"description":"Invalid rule (bad action, statuses, label, prefix or host)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the glitches:write scope or is not project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/glitches/rules/{id}":{"delete":{"tags":["Glitches"],"summary":"Delete one glitch rule by id.","description":"Deleting a rule never rewrites recorded events — past observations keep\nthe class they were recorded with; matching traffic resumes the\nplatform's default classification within a minute. A rule id from\nanother project reports 404.\n\nRequires the `glitches:write` scope and a project-scoped credential.","operationId":"deleteGlitchRule","parameters":[{"name":"id","in":"path","description":"Rule id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Rule deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the glitches:write scope or is not project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No such rule in this project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/integrations":{"get":{"tags":["Integrations"],"summary":"List source-control integrations.","description":"Returns all GitHub/GitLab/Bitbucket integrations attached to the caller's\nproject.","operationId":"listIntegrations","responses":{"200":{"description":"All integrations for the caller's project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListIntegrationsResponse"}}}},"400":{"description":"API key must be project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Integrations"],"summary":"Create a source-control integration.","description":"Attaches a Git provider repo to the caller's project and returns the created\nintegration plus the webhook URL and secret to configure on the provider.","operationId":"createIntegration","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntegrationBody"}}},"required":true},"responses":{"201":{"description":"Integration created; returns webhook URL + secret","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntegrationResponse"}}}},"400":{"description":"Invalid provider or duplicate integration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/integrations/github/installations":{"get":{"tags":["Integrations"],"summary":"List GitHub App installations.","description":"Returns the GitHub App installations registered to the caller's project.","operationId":"listGithubInstallations","responses":{"200":{"description":"GitHub App installations for the project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListInstallationsResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/integrations/github/installations/{installation_id}/token":{"post":{"tags":["Integrations"],"summary":"Mint an installation token.","description":"Returns a short-lived GitHub App installation access token for an\ninstallation owned by the caller's project.","operationId":"createGithubInstallationToken","parameters":[{"name":"installation_id","in":"path","description":"GitHub App installation id","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"A short-lived installation access token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Installation not found or not owned by this project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/integrations/github/repos":{"get":{"tags":["Integrations"],"summary":"List accessible GitHub repos.","description":"Returns the repositories the project's GitHub App installations can access,\naggregated across all active installations.","operationId":"listGithubRepos","responses":{"200":{"description":"Repositories accessible across the project's installations","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/integrations/{id}":{"get":{"tags":["Integrations"],"summary":"Get a source-control integration.","description":"Returns a single integration by id, scoped to the caller's project.","operationId":"getIntegration","parameters":[{"name":"id","in":"path","description":"Integration id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The integration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Integration not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Integrations"],"summary":"Update a source-control integration.","description":"Updates an integration's build/deploy settings (branch filter, auto-build,\nauto-deploy, preview, status) and returns the updated record.","operationId":"updateIntegration","parameters":[{"name":"id","in":"path","description":"Integration id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateIntegrationBody"}}},"required":true},"responses":{"200":{"description":"The updated integration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Integration not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Integrations"],"summary":"Delete a source-control integration.","description":"Detaches a Git provider repo from the caller's project and deletes the\nintegration record.","operationId":"deleteIntegration","parameters":[{"name":"id","in":"path","description":"Integration id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Integration deleted"},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Integration not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/kv/del":{"post":{"tags":["Key-Value"],"summary":"Delete keys.","description":"Removes one or more keys from the tenant's key-value store (batch delete).","operationId":"kvDel","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvDelRequest"}}},"required":true},"responses":{"200":{"description":"Key deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/kv/exists":{"post":{"tags":["Key-Value"],"summary":"Check if a key exists.","description":"Returns whether a key is present in the tenant's key-value store.","operationId":"kvExists","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvKeyRequest"}}},"required":true},"responses":{"200":{"description":"`{ exists: bool }`"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/kv/get":{"post":{"tags":["Key-Value"],"summary":"Fetch a value by key.","description":"Reads a single key from the tenant's key-value store; returns `value: null` if absent.","operationId":"kvGet","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvKeyRequest"}}},"required":true},"responses":{"200":{"description":"The stored value (or `value: null` if absent)"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/kv/keys":{"post":{"tags":["Key-Value"],"summary":"List keys.","description":"Returns the keys in the tenant's key-value store matching an optional glob pattern.","operationId":"kvKeys","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvKeysRequest"}}},"required":true},"responses":{"200":{"description":"`{ keys: [string] }` matching the pattern"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/kv/set":{"post":{"tags":["Key-Value"],"summary":"Set a value by key.","description":"Writes a value to the tenant's key-value store, with an optional TTL.","operationId":"kvSet","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvSetRequest"}}},"required":true},"responses":{"200":{"description":"Value set"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/lb":{"get":{"tags":["Load Balancer"],"summary":"List load balancers.","description":"Returns all load balancers belonging to the caller's project.","operationId":"listLoadBalancers","responses":{"200":{"description":"All load balancers for the caller's project","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LoadBalancerInfo"}}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the lb:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Load Balancer"],"summary":"Create a load balancer.","description":"Provisions a load balancer for the caller's project and returns its details.","operationId":"createLoadBalancer","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLbRequest"}}},"required":true},"responses":{"200":{"description":"Load balancer created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoadBalancerInfo"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the lb:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/lb/{id}":{"get":{"tags":["Load Balancer"],"summary":"Get a load balancer.","description":"Returns a single load balancer by id.","operationId":"getLoadBalancer","parameters":[{"name":"id","in":"path","description":"Load balancer id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The load balancer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoadBalancerInfo"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the lb:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Load balancer not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Load Balancer"],"summary":"Delete a load balancer.","description":"Removes a load balancer and its backends by id.","operationId":"deleteLoadBalancer","parameters":[{"name":"id","in":"path","description":"Load balancer id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Load balancer deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the lb:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Load balancer not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/lb/{id}/backends":{"post":{"tags":["Load Balancer"],"summary":"Add a backend to a load balancer.","description":"Registers a backend target on the load balancer and returns its details.","operationId":"addLoadBalancerBackend","parameters":[{"name":"id","in":"path","description":"Load balancer id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddBackendRequest"}}},"required":true},"responses":{"200":{"description":"Backend added","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendInfo"}}}},"400":{"description":"Load balancer not found or invalid backend","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the lb:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/lb/{id}/backends/{backend_id}":{"delete":{"tags":["Load Balancer"],"summary":"Remove a backend from a load balancer.","description":"Deletes a backend target from the load balancer by id.","operationId":"removeLoadBalancerBackend","parameters":[{"name":"id","in":"path","description":"Load balancer id (UUID)","required":true,"schema":{"type":"string"}},{"name":"backend_id","in":"path","description":"Backend id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Backend removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the lb:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Load balancer or backend not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/me":{"get":{"tags":["Account"],"summary":"Describe the current token.","description":"Returns the caller's identity, effective permissions and scopes, the MCP\ntools their scopes unlock, and their plan's rate-limit and API-key ceilings.","operationId":"getMe","responses":{"200":{"description":"The caller's identity, permissions, MCP tools, and plan limits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}},"401":{"description":"Missing or invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/notifications":{"get":{"tags":["Notifications"],"summary":"List notifications.","description":"Requires the `notifications:read` scope.","operationId":"listNotifications","responses":{"200":{"description":"List notifications"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing notifications:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Notifications"],"summary":"Send a notification.","description":"Requires the `notifications:write` scope.","operationId":"sendNotification","responses":{"200":{"description":"Send a notification"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing notifications:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/notifications/devices":{"post":{"tags":["Notifications"],"summary":"Register a notification device.","description":"Requires the `notifications:write` scope.","operationId":"registerNotificationDevice","responses":{"200":{"description":"Register a notification device"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing notifications:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/notifications/devices/{device_id}":{"delete":{"tags":["Notifications"],"summary":"Unregister a notification device.","description":"Requires the `notifications:write` scope.","operationId":"unregisterNotificationDevice","responses":{"200":{"description":"Unregister a notification device"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing notifications:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/notifications/preferences":{"get":{"tags":["Notifications"],"summary":"Get notification preferences.","description":"Requires the `notifications:read` scope.","operationId":"getNotificationPreferences","responses":{"200":{"description":"Get notification preferences"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing notifications:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Notifications"],"summary":"Update notification preferences.","description":"Requires the `notifications:write` scope.","operationId":"updateNotificationPreferences","responses":{"200":{"description":"Update notification preferences"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing notifications:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/notifications/read-all":{"post":{"tags":["Notifications"],"summary":"Mark all notifications read.","description":"Requires the `notifications:write` scope.","operationId":"markAllNotificationsRead","responses":{"200":{"description":"Mark all notifications read"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing notifications:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/notifications/unread-count":{"get":{"tags":["Notifications"],"summary":"Unread notification count.","description":"Requires the `notifications:read` scope.","operationId":"getUnreadCount","responses":{"200":{"description":"Unread notification count"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing notifications:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/notifications/{id}":{"get":{"tags":["Notifications"],"summary":"Get a notification.","description":"Requires the `notifications:read` scope.","operationId":"getNotification","responses":{"200":{"description":"Get a notification"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing notifications:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/notifications/{id}/read":{"post":{"tags":["Notifications"],"summary":"Mark a notification read.","description":"Requires the `notifications:write` scope.","operationId":"markNotificationRead","responses":{"200":{"description":"Mark a notification read"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing notifications:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/public/service-rates":{"get":{"tags":["Billing"],"operationId":"get_public_service_rates","responses":{"200":{"description":"The public rate card: one row per billable, enabled, service-mapped non-AI metric. Sell-side only: our_cost_cents never leaves this query."},"404":{"description":"Billing not configured on this deployment"}}}},"/v1/registry/v2/":{"get":{"tags":["Registry"],"summary":"Check the registry API version.","description":"Returns the OCI Distribution API version supported by the registry.","operationId":"registryVersionCheck","responses":{"200":{"description":"OCI Distribution API version check"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/registry/v2/_catalog":{"get":{"tags":["Registry"],"summary":"List the repository catalog.","description":"Returns the catalog of repositories in the registry.","operationId":"getRegistryCatalog","responses":{"200":{"description":"Repository catalog"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/registry/v2/{project_id}/{repository}/blobs/uploads/":{"post":{"tags":["Registry"],"summary":"Start a blob upload.","description":"Begins an OCI blob upload session and returns the upload location.","operationId":"startRegistryBlobUpload","parameters":[{"name":"project_id","in":"path","description":"Project id","required":true,"schema":{"type":"string"}},{"name":"repository","in":"path","description":"Repository name","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Blob upload session started"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/registry/v2/{project_id}/{repository}/blobs/{digest}":{"get":{"tags":["Registry"],"summary":"Get a blob.","description":"Downloads an OCI blob by digest.","operationId":"getRegistryBlob","parameters":[{"name":"project_id","in":"path","description":"Project id","required":true,"schema":{"type":"string"}},{"name":"repository","in":"path","description":"Repository name","required":true,"schema":{"type":"string"}},{"name":"digest","in":"path","description":"Blob digest","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Blob content"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"head":{"tags":["Registry"],"summary":"Check a blob exists.","description":"Returns headers indicating whether an OCI blob exists.","operationId":"headRegistryBlob","parameters":[{"name":"project_id","in":"path","description":"Project id","required":true,"schema":{"type":"string"}},{"name":"repository","in":"path","description":"Repository name","required":true,"schema":{"type":"string"}},{"name":"digest","in":"path","description":"Blob digest","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Blob existence/headers"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/registry/v2/{project_id}/{repository}/manifests/{reference}":{"get":{"tags":["Registry"],"summary":"Get a manifest.","description":"Returns an OCI image manifest by tag or digest.","operationId":"getRegistryManifest","parameters":[{"name":"project_id","in":"path","description":"Project id","required":true,"schema":{"type":"string"}},{"name":"repository","in":"path","description":"Repository name","required":true,"schema":{"type":"string"}},{"name":"reference","in":"path","description":"Tag or digest","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OCI manifest"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Registry"],"summary":"Store a manifest.","description":"Uploads an OCI image manifest under a tag or digest.","operationId":"putRegistryManifest","parameters":[{"name":"project_id","in":"path","description":"Project id","required":true,"schema":{"type":"string"}},{"name":"repository","in":"path","description":"Repository name","required":true,"schema":{"type":"string"}},{"name":"reference","in":"path","description":"Tag or digest","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"OCI manifest","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"201":{"description":"Manifest stored"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Registry"],"summary":"Delete a manifest.","description":"Removes an OCI image manifest by tag or digest.","operationId":"deleteRegistryManifest","parameters":[{"name":"project_id","in":"path","description":"Project id","required":true,"schema":{"type":"string"}},{"name":"repository","in":"path","description":"Repository name","required":true,"schema":{"type":"string"}},{"name":"reference","in":"path","description":"Tag or digest","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Manifest deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"head":{"tags":["Registry"],"summary":"Check a manifest exists.","description":"Returns headers indicating whether an OCI manifest exists.","operationId":"headRegistryManifest","parameters":[{"name":"project_id","in":"path","description":"Project id","required":true,"schema":{"type":"string"}},{"name":"repository","in":"path","description":"Repository name","required":true,"schema":{"type":"string"}},{"name":"reference","in":"path","description":"Tag or digest","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Manifest existence/headers"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/registry/v2/{project_id}/{repository}/tags/list":{"get":{"tags":["Registry"],"summary":"List tags.","description":"Returns the tags available for a repository.","operationId":"listRegistryTags","parameters":[{"name":"project_id","in":"path","description":"Project id","required":true,"schema":{"type":"string"}},{"name":"repository","in":"path","description":"Repository name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tag list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/run/services":{"get":{"tags":["Compute"],"summary":"List Scalix Run services.","description":"Returns all Scalix Run services for the caller's project.","operationId":"listServices","responses":{"200":{"description":"Service list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Compute"],"summary":"Deploy a Scalix Run service.","description":"Deploys a Scalix Run service and returns the created service.","operationId":"createService","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunServiceDeployRequest"}}},"required":true},"responses":{"201":{"description":"Service deployed"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/run/services/{id}":{"get":{"tags":["Compute"],"summary":"Get a Scalix Run service.","description":"Returns a single Scalix Run service by id.","operationId":"getService","parameters":[{"name":"id","in":"path","description":"Service id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Service details"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Compute"],"summary":"Update a Scalix Run service.","description":"Updates a Scalix Run service (e.g. scaling) and returns the new state.","operationId":"updateService","parameters":[{"name":"id","in":"path","description":"Service id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunServiceUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Service updated"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Compute"],"summary":"Delete a Scalix Run service.","description":"Removes a Scalix Run service by id.","operationId":"deleteService","parameters":[{"name":"id","in":"path","description":"Service id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Service deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/run/services/{id}/instances":{"get":{"tags":["Compute"],"summary":"List service instances.","description":"Returns the running instances of a Scalix Run service.","operationId":"listServiceInstances","parameters":[{"name":"id","in":"path","description":"Service id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Service instances"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/run/services/{id}/metrics":{"get":{"tags":["Compute"],"summary":"Get service live instance state.","description":"Returns healthy/total instance counts and in-flight request totals for a\nScalix Run service. Request-level RED metrics (requests/sec, errors/sec,\nlatency percentiles) are served by\n`GET /v1/metering/services/run-service/{id}/metrics`, whose response\ncarries `available:false` with a message when the deployment has no\nmetrics backend.","operationId":"getServiceMetrics","parameters":[{"name":"id","in":"path","description":"Service id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Live instance state"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/run/services/{id}/revisions":{"get":{"tags":["Compute"],"summary":"List service revisions.","description":"Returns the revision history of a Scalix Run service.","operationId":"listServiceRevisions","parameters":[{"name":"id","in":"path","description":"Service id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Service revisions"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/run/services/{id}/rollback":{"post":{"tags":["Compute"],"summary":"Roll back a service.","description":"Rolls a Scalix Run service back to a previous revision.","operationId":"rollbackService","parameters":[{"name":"id","in":"path","description":"Service id","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Rollback request (target revision)","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Service rolled back"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/sandboxes":{"get":{"tags":["Sandboxes"],"summary":"List your sandboxes.","operationId":"sandboxList","responses":{"200":{"description":"`{sandboxes: [...], total}`"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Sandboxes"],"summary":"Create an ephemeral sandbox.","description":"Boots an isolated microVM. Ephemeral sandboxes are disposable: they stop\nat their idle or hard timeout and nothing on the rootfs persists past\nstop. Compute is billed per vCPU-hour and GB-hour of allocation while\nrunning.","operationId":"sandboxCreate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxCreateRequest"}}},"required":true},"responses":{"201":{"description":"Sandbox created (initially PROVISIONING)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxInfo"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Credit exhausted or plan limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"No capacity for the requested resources","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/sandboxes/{id}":{"get":{"tags":["Sandboxes"],"summary":"Get a sandbox by id.","operationId":"sandboxGet","parameters":[{"name":"id","in":"path","description":"Sandbox id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Sandbox details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxInfo"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Sandboxes"],"summary":"Delete a sandbox and tear down its microVM.","operationId":"sandboxDelete","parameters":[{"name":"id","in":"path","description":"Sandbox id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/sandboxes/{id}/commands":{"post":{"tags":["Sandboxes"],"summary":"Run a command inside a running sandbox (synchronous).","operationId":"sandboxRunCommand","parameters":[{"name":"id","in":"path","description":"Sandbox id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxCommandRequest"}}},"required":true},"responses":{"200":{"description":"Command result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxCommandResult"}}}},"400":{"description":"Sandbox is not running","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/sandboxes/{id}/extend":{"post":{"tags":["Sandboxes"],"summary":"Extend a sandbox's hard deadline.","operationId":"sandboxExtend","parameters":[{"name":"id","in":"path","description":"Sandbox id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxExtendRequest"}}},"required":true},"responses":{"200":{"description":"Updated sandbox","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxInfo"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/sandboxes/{id}/files":{"post":{"tags":["Sandboxes"],"summary":"Write files into a sandbox.","operationId":"sandboxWriteFiles","parameters":[{"name":"id","in":"path","description":"Sandbox id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxWriteFilesRequest"}}},"required":true},"responses":{"204":{"description":"Files written"},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Path outside the allowed guest roots","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/sandboxes/{id}/files/{path}":{"get":{"tags":["Sandboxes"],"summary":"Read a file from a sandbox. The guest path follows `/files/`.","operationId":"sandboxReadFile","parameters":[{"name":"id","in":"path","description":"Sandbox id","required":true,"schema":{"type":"string"}},{"name":"path","in":"path","description":"Guest file path, e.g. `app/output.json`","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File content (application/octet-stream)"},"404":{"description":"File or sandbox not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/sandboxes/{id}/snapshot":{"post":{"tags":["Sandboxes"],"summary":"Snapshot a sandbox - not available.","description":"Ephemeral sandboxes are disposable; state does not persist past stop.\nThis endpoint returns 501 until snapshots ship (demand-gated).","operationId":"sandboxSnapshot","parameters":[{"name":"id","in":"path","description":"Sandbox id","required":true,"schema":{"type":"string"}}],"responses":{"501":{"description":"Snapshots are not available for ephemeral sandboxes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/search":{"get":{"tags":["Search"],"summary":"Run a search.","description":"Runs a query against the curated Scalix Search index and returns ranked results.","operationId":"searchIndex","parameters":[{"name":"q","in":"query","description":"Search query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Search results"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/search/ingest/run":{"post":{"tags":["Search"],"summary":"Run a search ingest.","description":"Triggers an ingest run that crawls and indexes registered sources.","operationId":"runSearchIngest","responses":{"200":{"description":"Ingest run triggered"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/search/sources":{"get":{"tags":["Search"],"summary":"List search sources.","description":"Returns the curated sources registered in the search index.","operationId":"listSearchSources","responses":{"200":{"description":"Curated source list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Search"],"summary":"Upsert a search source.","description":"Creates or updates a curated source in the search index.","operationId":"upsertSearchSource","requestBody":{"description":"Upsert-source request","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Source upserted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/search/stats":{"get":{"tags":["Search"],"summary":"Get search stats.","description":"Returns statistics about the search index.","operationId":"getSearchStats","responses":{"200":{"description":"Index stats"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/shield/config":{"get":{"tags":["Shield"],"summary":"Get Shield config.","description":"Returns the Shield configuration (default action, challenge settings) for the\ncaller's project.","operationId":"getShieldConfig","responses":{"200":{"description":"Shield configuration for the caller's project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScopeConfig"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:read scope or is not project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Shield"],"summary":"Update Shield config.","description":"Replaces the Shield configuration for the caller's project. Requires the Pro\nplan or higher.","operationId":"updateShieldConfig","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScopeConfig"}}},"required":true},"responses":{"200":{"description":"Updated shield configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScopeConfig"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Requires Pro plan, the waf:write scope, or a project-scoped token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/shield/crawlers":{"get":{"tags":["Shield"],"summary":"List Shield crawlers.","description":"Returns the known AI crawlers with their per-project policy and traffic\nstats, plus any custom user-defined crawler rules.","operationId":"listShieldCrawlers","responses":{"200":{"description":"Known crawlers (with per-scope policy + stats) and custom rules","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:read scope or is not project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/shield/crawlers/{id}/ip-ranges":{"put":{"tags":["Shield"],"summary":"Set a crawler's verification IP ranges.","description":"Sets the IP addresses or CIDR ranges used to verify a crawler's source IP.\nRequires the Pro plan or higher.","operationId":"setShieldCrawlerIpRanges","parameters":[{"name":"id","in":"path","description":"Crawler id (e.g. `gptbot`)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IpRangesRequest"}}},"required":true},"responses":{"200":{"description":"IP ranges set for the crawler","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid IP or CIDR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Requires Pro plan, the waf:write scope, or a project-scoped token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Unknown crawler","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/shield/crawlers/{id}/policy":{"put":{"tags":["Shield"],"summary":"Set a crawler policy.","description":"Sets the access policy (allow / block / rate-limit) for a known crawler in\nthe caller's project. Policy controls require the Pro plan or higher.","operationId":"setShieldCrawlerPolicy","parameters":[{"name":"id","in":"path","description":"Crawler id (e.g. `gptbot`)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrawlerPolicy"}}},"required":true},"responses":{"200":{"description":"Policy set for the crawler","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Requires Pro plan, the waf:write scope, or a project-scoped token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Unknown crawler","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Shield"],"summary":"Clear a crawler policy.","description":"Removes the access policy for a crawler, reverting it to the project default.\nPolicy controls require the Pro plan or higher.","operationId":"clearShieldCrawlerPolicy","parameters":[{"name":"id","in":"path","description":"Crawler id (e.g. `gptbot`)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Policy cleared","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Requires Pro plan, the waf:write scope, or a project-scoped token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No policy set for crawler","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/shield/custom":{"post":{"tags":["Shield"],"summary":"Create a custom Shield rule.","description":"Adds a customer-defined crawler rule matched by User-Agent substring, with\nits own access policy. Requires the Pro plan or higher.","operationId":"createShieldCustomRule","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomRuleRequest"}}},"required":true},"responses":{"200":{"description":"Custom rule created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomRule"}}}},"400":{"description":"Invalid rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Requires Pro plan, the waf:write scope, or a project-scoped token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/shield/custom/{id}":{"put":{"tags":["Shield"],"summary":"Update a custom Shield rule.","description":"Updates the access policy of an existing custom crawler rule. Requires the\nPro plan or higher.","operationId":"updateShieldCustomRule","parameters":[{"name":"id","in":"path","description":"Custom rule id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrawlerPolicy"}}},"required":true},"responses":{"200":{"description":"Custom rule policy updated","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Requires Pro plan, the waf:write scope, or a project-scoped token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Custom rule not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Shield"],"summary":"Delete a custom Shield rule.","description":"Removes a custom crawler rule by id. Requires the Pro plan or higher.","operationId":"deleteShieldCustomRule","parameters":[{"name":"id","in":"path","description":"Custom rule id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Custom rule deleted","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Requires Pro plan, the waf:write scope, or a project-scoped token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Custom rule not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/shield/events":{"get":{"tags":["Shield"],"summary":"List Shield events.","description":"Returns recent Shield crawler events for the project, paginated.","operationId":"listShieldEvents","parameters":[{"name":"cursor","in":"query","description":"Opaque keyset cursor (preferred); returns {data, has_more, next_cursor}","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Zero-based page index (legacy offset mode; ignored when cursor is set)","required":false,"schema":{"type":"integer","minimum":0}},{"name":"limit","in":"query","description":"Page size (default 50, max 200)","required":false,"schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"Recent shield events for the project (paginated)","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:read scope or is not project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/shield/robots-txt":{"get":{"tags":["Shield"],"summary":"Generate robots.txt.","description":"Returns a `robots.txt` generated from the project's Shield crawler policies.\n\nThis is what Shield serves for apps that have NO robots.txt of their own.\nAn app that ships one has it served verbatim with these crawler rules\nappended instead, so this is not necessarily the file a crawler receives.\nYou do not need to copy this into your project.","operationId":"getShieldRobotsTxt","responses":{"200":{"description":"Generated robots.txt for the project","content":{"text/plain":{"schema":{"type":"string"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:read scope or is not project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/shield/stats":{"get":{"tags":["Shield"],"summary":"Get Shield statistics.","description":"Returns aggregate request, block, and rate-limit counts broken down by\ncrawler for the caller's project.","operationId":"getShieldStats","responses":{"200":{"description":"Aggregate request/block/rate-limit counts, by crawler","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:read scope or is not project-scoped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/storage/buckets":{"get":{"tags":["Storage"],"summary":"List buckets.","description":"Returns all storage buckets for the caller's project.","operationId":"listBuckets","responses":{"200":{"description":"Bucket list"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Storage"],"summary":"Create a bucket.","description":"Creates a new storage bucket.","operationId":"createBucket","responses":{"201":{"description":"Bucket created"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/storage/buckets/{bucket}/objects":{"get":{"tags":["Storage"],"summary":"List objects.","description":"Returns the objects in a bucket, optionally filtered by key prefix.","operationId":"listObjects","parameters":[{"name":"bucket","in":"path","description":"Bucket name","required":true,"schema":{"type":"string"}},{"name":"prefix","in":"query","description":"Key prefix filter","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max objects to return (default 100)","required":false,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Object listing"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/storage/buckets/{bucket}/objects/{key}":{"get":{"tags":["Storage"],"summary":"Get an object.","description":"Downloads the contents of an object from a bucket.","operationId":"getObject","parameters":[{"name":"bucket","in":"path","description":"Bucket name","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","description":"Object key","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Object content"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Storage"],"summary":"Upload an object.","description":"Stores raw bytes as an object in a bucket.","operationId":"putObject","parameters":[{"name":"bucket","in":"path","description":"Bucket name","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","description":"Object key","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Raw object bytes","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}},"required":true},"responses":{"200":{"description":"Object stored"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Storage"],"summary":"Delete an object.","description":"Removes an object from a bucket.","operationId":"deleteObject","parameters":[{"name":"bucket","in":"path","description":"Bucket name","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","description":"Object key","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Object deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"head":{"tags":["Storage"],"summary":"Get object metadata.","description":"Returns an object's metadata headers without its body.","operationId":"headObject","parameters":[{"name":"bucket","in":"path","description":"Bucket name","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","description":"Object key","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Object metadata headers"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/storage/buckets/{name}":{"delete":{"tags":["Storage"],"summary":"Delete a bucket.","description":"Removes a storage bucket by name.","operationId":"deleteBucket","parameters":[{"name":"name","in":"path","description":"Bucket name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Bucket deleted"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/storage/presign":{"post":{"tags":["Storage"],"summary":"Presign an object URL.","description":"Returns a presigned URL for direct upload or download of an object.","operationId":"presignObject","requestBody":{"description":"Presign request (bucket, key, method, expiry)","content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Presigned URL"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/support/chat/sessions":{"get":{"tags":["Support"],"summary":"List support chat sessions.","description":"Requires an org credential (no dedicated scope).","operationId":"listSupportChatSessions","responses":{"200":{"description":"List support chat sessions"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Support"],"summary":"Start a support chat session.","description":"Requires an org credential (no dedicated scope).","operationId":"createSupportChatSession","responses":{"200":{"description":"Start a support chat session"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/support/chat/sessions/{id}/messages":{"get":{"tags":["Support"],"summary":"List support chat messages.","description":"Requires an org credential (no dedicated scope).","operationId":"listSupportChatMessages","responses":{"200":{"description":"List support chat messages"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Support"],"summary":"Post a support chat message.","description":"Requires an org credential (no dedicated scope).","operationId":"postSupportChatMessage","responses":{"200":{"description":"Post a support chat message"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/support/tickets":{"get":{"tags":["Support"],"summary":"List support tickets.","description":"Requires an org credential (no dedicated scope).","operationId":"listSupportTickets","responses":{"200":{"description":"List support tickets"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Support"],"summary":"Open a support ticket.","description":"Requires an org credential (no dedicated scope).","operationId":"createSupportTicket","responses":{"200":{"description":"Open a support ticket"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/support/tickets/{id}":{"get":{"tags":["Support"],"summary":"Get a support ticket.","description":"Requires an org credential (no dedicated scope).","operationId":"getSupportTicket","responses":{"200":{"description":"Get a support ticket"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"put":{"tags":["Support"],"summary":"Update a support ticket.","description":"Requires an org credential (no dedicated scope).","operationId":"updateSupportTicket","responses":{"200":{"description":"Update a support ticket"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/support/tickets/{id}/close":{"post":{"tags":["Support"],"summary":"Close a support ticket.","description":"Requires an org credential (no dedicated scope).","operationId":"closeSupportTicket","responses":{"200":{"description":"Close a support ticket"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/support/tickets/{id}/comments":{"get":{"tags":["Support"],"summary":"List ticket comments.","description":"Requires an org credential (no dedicated scope).","operationId":"listSupportTicketComments","responses":{"200":{"description":"List ticket comments"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Support"],"summary":"Comment on a support ticket.","description":"Requires an org credential (no dedicated scope).","operationId":"addSupportTicketComment","responses":{"200":{"description":"Comment on a support ticket"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/usage/keys":{"get":{"tags":["Metering"],"summary":"List per-key usage for the org.","description":"Returns each of the organization's API keys with its request count for the\ncurrent billing month. Requires the `metering:read` scope.","operationId":"getKeysUsage","responses":{"200":{"description":"Per-API-key request counts for the current month","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeysUsageResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the metering:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/usage/keys/{key_id}":{"get":{"tags":["Metering"],"summary":"Get usage for one API key.","description":"Returns the request count for a single API key this billing month. Requires\nthe `metering:read` scope; the key must belong to the caller's org.","operationId":"getKeyUsage","parameters":[{"name":"key_id","in":"path","description":"API key id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Usage detail for one API key this month","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyUsageDetail"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the metering:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Key not found in this organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"501":{"description":"Billing not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/user/budget":{"get":{"tags":["Metering"],"summary":"Get the caller's budget.","description":"Returns current usage (AI tokens, storage, compute hours), the plan's\nallowances, and the remaining headroom for each.","operationId":"getUserBudget","responses":{"200":{"description":"Usage, plan limits, and remaining allowance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Database error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/user/info":{"get":{"tags":["Account"],"summary":"Get the caller's account profile.","description":"Returns the authenticated user's id, email, name, plan, and status. Fields\nafter `status` are present only when a stored user record exists.","operationId":"getUserInfo","responses":{"200":{"description":"The caller's account profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserInfo"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Database error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/user/stats":{"get":{"tags":["Metering"],"summary":"Get the caller's usage stats.","description":"Returns a per-service usage breakdown (AI, storage, compute, bandwidth,\nfunctions) for the current month.","operationId":"getUserStats","responses":{"200":{"description":"Per-service usage for the current month","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Database error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/vpc":{"get":{"tags":["VPC"],"summary":"List VPCs.","description":"Returns all VPCs belonging to the caller's project.","operationId":"listVpcs","responses":{"200":{"description":"All VPCs for the caller's project","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VpcJson"}}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the vpc:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["VPC"],"summary":"Create a VPC.","description":"Provisions a VPC for the caller's project. Currently returns 501 —\nenforcement and durable storage are a planned capability.","operationId":"createVpc","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVpcBody"}}},"required":true},"responses":{"201":{"description":"VPC created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VpcJson"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the vpc:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"501":{"description":"VPC provisioning not yet implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/vpc/{id}":{"get":{"tags":["VPC"],"summary":"Get a VPC.","description":"Returns a single VPC by id.","operationId":"getVpc","parameters":[{"name":"id","in":"path","description":"VPC id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The VPC","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VpcJson"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the vpc:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"VPC not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["VPC"],"summary":"Delete a VPC.","description":"Removes a VPC and its peers by id.","operationId":"deleteVpc","parameters":[{"name":"id","in":"path","description":"VPC id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"VPC deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the vpc:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"VPC not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/vpc/{id}/config":{"get":{"tags":["VPC"],"summary":"Get a VPC's config.","description":"Returns the rendered VPN client configuration file for the VPC.","operationId":"getVpcConfig","parameters":[{"name":"id","in":"path","description":"VPC id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"configuration for the VPC","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VpcConfigResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the vpc:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"VPC not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/vpc/{id}/peers":{"get":{"tags":["VPC"],"summary":"List a VPC's peers.","description":"Returns all peers registered in the VPC.","operationId":"listVpcPeers","parameters":[{"name":"id","in":"path","description":"VPC id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"All peers in the VPC","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VpcPeerJson"}}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the vpc:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"VPC not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["VPC"],"summary":"Add a peer to a VPC.","description":"Registers a peer in the VPC. Currently returns 501 — peer\nenforcement and durable storage are a planned capability.","operationId":"addVpcPeer","parameters":[{"name":"id","in":"path","description":"VPC id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddPeerBody"}}},"required":true},"responses":{"201":{"description":"Peer added","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VpcPeerJson"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the vpc:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"501":{"description":"VPC provisioning not yet implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/vpc/{id}/peers/{peer_id}":{"delete":{"tags":["VPC"],"summary":"Remove a peer from a VPC.","description":"Deletes a peer from the VPC by id.","operationId":"removeVpcPeer","parameters":[{"name":"id","in":"path","description":"VPC id (UUID)","required":true,"schema":{"type":"string"}},{"name":"peer_id","in":"path","description":"Peer id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Peer removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the vpc:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"VPC or peer not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/waf/events":{"get":{"tags":["WAF"],"summary":"List recent WAF events.","description":"Returns the most recent web application firewall events (up to 100).","operationId":"listWafEvents","responses":{"200":{"description":"Recent WAF events (up to 100)","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WafEvent"}}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/waf/rules":{"get":{"tags":["WAF"],"summary":"List WAF rules.","description":"Returns all configured web application firewall rules.","operationId":"listWafRules","responses":{"200":{"description":"All WAF rules","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WafRule"}}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"post":{"tags":["WAF"],"summary":"Create a WAF rule.","description":"Adds a new web application firewall rule and returns the created rule.","operationId":"createWafRule","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRuleRequest"}}},"required":true},"responses":{"200":{"description":"Rule created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WafRule"}}}},"400":{"description":"Rule uses a pattern/action the WAF does not enforce","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/waf/rules/{id}":{"put":{"tags":["WAF"],"summary":"Update a WAF rule.","description":"Replaces the configuration of an existing web application firewall rule.","operationId":"updateWafRule","parameters":[{"name":"id","in":"path","description":"Rule id (UUID)","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRuleRequest"}}},"required":true},"responses":{"200":{"description":"Rule updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WafRule"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Rule not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["WAF"],"summary":"Delete a WAF rule.","description":"Removes a web application firewall rule by id.","operationId":"deleteWafRule","parameters":[{"name":"id","in":"path","description":"Rule id (UUID)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Rule deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:write scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Rule not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}},"/v1/waf/stats":{"get":{"tags":["WAF"],"summary":"Get WAF statistics.","description":"Returns combined web application firewall and DDoS-detector counters.","operationId":"getWafStats","responses":{"200":{"description":"Combined WAF and DDoS statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WafStatsResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token lacks the waf:read scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]}]}}},"components":{"schemas":{"AddBackendRequest":{"type":"object","required":["url"],"properties":{"url":{"type":"string"},"weight":{"type":"integer","format":"int32","minimum":0}}},"AddDomainBody":{"type":"object","description":"Request body for `POST /v1/domains` — the custom domain to register.","required":["domain"],"properties":{"domain":{"type":"string","description":"Fully-qualified domain to attach, e.g. `app.example.com`.","example":"app.example.com"},"run_service":{"type":["string","null"],"description":"Optional Scalix Run service (by name) this domain should serve. When\nset, requests to the domain are proxied to the service exactly like\n`{name}.run.scalix.world`; when omitted, the domain serves the\nproject's API surface. The service must belong to the caller's\nproject.","example":"my-frontend"},"storage_bucket":{"type":["string","null"]},"function_name":{"type":["string","null"],"description":"Optional Function (by globally-unique name) this domain serves. Requests\nto the domain invoke the function's HTTP handler exactly like\n`{name}.fn.scalix.world`. Mutually exclusive with the other targets."}}},"AddDomainResponse":{"type":"object","description":"Response for `POST /v1/domains` — the created domain plus DNS setup steps.","required":["domain","instructions"],"properties":{"domain":{"$ref":"#/components/schemas/DomainJson"},"instructions":{"$ref":"#/components/schemas/DomainInstructions"}}},"AddPeerBody":{"type":"object","description":"Request body for `POST /v1/vpc/{id}/peers`. Mirrors `scalix_vpc::AddPeerRequest`.\nDocumentation-only (see `CreateVpcBody`).","required":["name","public_key","allowed_ips"],"properties":{"name":{"type":"string"},"public_key":{"type":"string"},"allowed_ips":{"type":"array","items":{"type":"string"}},"endpoint":{"type":["string","null"]}}},"AiStat":{"type":"object","required":["tokens_used"],"properties":{"tokens_used":{"type":"number","format":"double"}}},"AuditAction":{"type":"string","enum":["data_access","data_modify","data_delete","auth_login","auth_fail","config_change","api_key_create","api_key_revoke","api_key_rotate","member_add","member_remove","compliance_export","compliance_erasure"]},"AuditEntry":{"type":"object","required":["id","timestamp","tenant_id","actor","action","resource","source_ip"],"properties":{"id":{"type":"string","format":"uuid"},"timestamp":{"type":"string","format":"date-time"},"tenant_id":{"type":"string"},"actor":{"type":"string"},"action":{"$ref":"#/components/schemas/AuditAction"},"resource":{"type":"string"},"details":{"type":["string","null"]},"source_ip":{"type":"string"},"request_id":{"type":["string","null"]},"entry_hash":{"type":"string"},"prev_hash":{"type":"string"}}},"AuthResponse":{"type":"object","description":"Authentication tokens plus the authenticated user.","required":["access_token","refresh_token","expires_in","expires_at","token_type","user"],"properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"expires_in":{"type":"integer","format":"int64"},"expires_at":{"type":"string","format":"date-time"},"token_type":{"type":"string","example":"bearer"},"user":{"$ref":"#/components/schemas/User"}}},"BackendInfo":{"type":"object","required":["id","url","weight","healthy","active_conns"],"properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"weight":{"type":"integer","format":"int32","minimum":0},"healthy":{"type":"boolean"},"active_conns":{"type":"integer","format":"int32","minimum":0}}},"BandwidthStat":{"type":"object","required":["gb_used"],"properties":{"gb_used":{"type":"number","format":"double"}}},"BatchSqlRequest":{"type":"object","description":"A batch of SQL queries executed in one request (each runs independently).","required":["queries"],"properties":{"queries":{"type":"array","items":{"$ref":"#/components/schemas/SqlRequest"}}}},"BillingPlan":{"type":"object","description":"A billing plan as the pricing page and console BillingPage render it.","required":["id","name","slug","price_cents","max_team_seats","max_projects","support_tier","sla_pct","features"],"properties":{"id":{"type":"string","description":"Plan id (\"free\", \"starter\", \"pro\", …).","example":"pro"},"name":{"type":"string","description":"Display name.","example":"Pro"},"slug":{"type":"string","description":"URL slug.","example":"pro"},"price_cents":{"type":"integer","format":"int64","description":"Base monthly price, in cents (USD).","example":2000},"annual_price_cents":{"type":["integer","null"],"format":"int64","description":"Annual-billing price, in cents (USD); null when the plan has no\nannual price."},"max_team_seats":{"type":"integer","format":"int32","description":"Maximum team seats included.","example":10},"max_projects":{"type":"integer","format":"int32","description":"Maximum projects included.","example":25},"support_tier":{"type":"string","description":"Support tier (\"community\", \"standard\", \"priority\").","example":"standard"},"sla_pct":{"type":"number","format":"double","description":"SLA percentage.","example":99.9},"features":{"type":"array","items":{"type":"string"},"description":"Feature list shown on the pricing page."}}},"BillingPlanList":{"type":"object","description":"The plan list response.","required":["plans"],"properties":{"plans":{"type":"array","items":{"$ref":"#/components/schemas/BillingPlan"}}}},"BranchTimelineEndpoint":{"type":"object","description":"Connection endpoint of the branch's compute worker.","required":["host","port"],"properties":{"host":{"type":"string"},"port":{"type":"integer","format":"int32"}}},"BranchTimelineRequest":{"type":"object","description":"Request to branch a timeline.","properties":{"new_timeline_id":{"type":["string","null"],"description":"Explicit id (UUID) for the new branch timeline; server-generated when\nomitted."},"branch_lsn":{"type":"integer","format":"int64","description":"LSN to branch at; `0` (the default) branches at the latest recoverable\npoint.","minimum":0}}},"BranchTimelineResponse":{"type":"object","description":"A created branch, routed and ready.","required":["timeline_id","parent_timeline_id","branch_lsn","endpoint","status"],"properties":{"timeline_id":{"type":"string","description":"The new branch timeline id."},"parent_timeline_id":{"type":"string","description":"The timeline the branch was taken from."},"branch_lsn":{"type":"integer","format":"int64","description":"LSN the branch was taken at (`0` = latest).","minimum":0},"endpoint":{"$ref":"#/components/schemas/BranchTimelineEndpoint"},"status":{"type":"string","description":"Always `ready` on success.","example":"ready"}}},"BudgetLimits":{"type":"object","description":"Plan allowances.","required":["ai_tokens","storage_gb","compute_hours"],"properties":{"ai_tokens":{"type":"integer","format":"int64"},"storage_gb":{"type":"number","format":"double"},"compute_hours":{"type":"number","format":"double"}}},"BudgetResponse":{"type":"object","description":"Response for `GET /v1/user/budget`.","required":["user_id","usage","limits","remaining"],"properties":{"user_id":{"type":"string"},"usage":{"$ref":"#/components/schemas/BudgetUsage"},"limits":{"$ref":"#/components/schemas/BudgetLimits"},"remaining":{"$ref":"#/components/schemas/BudgetUsage"}}},"BudgetUsage":{"type":"object","description":"Usage figures (floats) — used for the current usage and remaining allowance.","required":["ai_tokens","storage_gb","compute_hours"],"properties":{"ai_tokens":{"type":"number","format":"double"},"storage_gb":{"type":"number","format":"double"},"compute_hours":{"type":"number","format":"double"}}},"BuildCreateRequest":{"type":"object","description":"A source build to start.","required":["source_type"],"properties":{"source_type":{"type":"string","description":"Where the source comes from: `git` or `tarball`.","example":"git"},"source_url":{"type":["string","null"],"description":"Repository or archive URL. Must be reachable from the builder.","example":"https://github.com/acme/api.git"},"source_ref":{"type":["string","null"],"description":"Branch, tag or commit to build. Defaults to `main`. This is the branch\nfield: `git_ref` is not recognised and is ignored if sent.","example":"main"},"auth_token":{"type":["string","null"],"format":"password","description":"Credential for a private repository, used as the password in the clone\nURL. A fine-grained token with read-only Contents access on that one\nrepository is enough. It is held in memory for the build only: never\nstored, never written to build logs or error messages. Omit this when\nthe Scalix GitHub App is installed for the project - a short-lived\ninstallation token is then minted per build and injected automatically."},"dockerfile_path":{"type":["string","null"],"description":"Path to the Dockerfile within the source tree. Auto-detected if omitted.","example":"Dockerfile"},"image_tag":{"type":["string","null"],"description":"Tag for the resulting image. Auto-generated if omitted.","example":"api:1.4.0"},"build_args":{"type":["object","null"],"description":"Build-time ARGs passed to the builder. Project environment variables are\nmerged in as well; values sent here win. These are stored on the build\nrecord and readable back from `GET /v1/build/{id}`, so treat them as\nnon-secret: use them for things like a public API base URL, not tokens."},"timeout_seconds":{"type":["integer","null"],"format":"int32","description":"Build timeout in seconds. Default 600, maximum 3600.","example":600}}},"BulkImportBody":{"type":"object","description":"Request body for `POST /v1/env/bulk` — import many variables at once.","required":["variables"],"properties":{"variables":{"type":"array","items":{"$ref":"#/components/schemas/SetEnvBody"}}}},"ChangePlanRequest":{"type":"object","description":"In-place plan change request.","required":["new_plan"],"properties":{"new_plan":{"type":"string","description":"Target plan id. The console sends `price_id` — accepted as an\nalias.","example":"team"}}},"ChatCompletionChoice":{"type":"object","description":"One completion choice: index, message, finish reason.","required":["index","message"],"properties":{"index":{"type":"integer","format":"int64","description":"Choice index."},"message":{"$ref":"#/components/schemas/ChatCompletionMessage","description":"The generated message."},"finish_reason":{"type":["string","null"],"description":"Why generation stopped (`stop`, `length`, `tool_calls`, …)."}}},"ChatCompletionMessage":{"type":"object","description":"A single chat message (OpenAI-compatible).","required":["role","content"],"properties":{"role":{"type":"string","description":"Message author role."},"content":{"type":"string","description":"Message content."}}},"ChatCompletionRequest":{"type":"object","description":"A chat-completion request (OpenAI-compatible). Streams via SSE when `stream`.","required":["messages","model"],"properties":{"messages":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessage"}},"model":{"type":"string","example":"scalix-auto/free"},"max_tokens":{"type":["integer","null"],"format":"int64"},"temperature":{"type":["number","null"],"format":"double"},"top_p":{"type":["number","null"],"format":"double"},"stream":{"type":["boolean","null"]}}},"ChatCompletionResponse":{"type":"object","description":"A chat-completion response (OpenAI-compatible envelope).","required":["id","object","created","model","choices","usage"],"properties":{"id":{"type":"string"},"object":{"type":"string","example":"chat.completion"},"created":{"type":"integer","format":"int64"},"model":{"type":"string"},"choices":{"type":"array","items":{"$ref":"#/components/schemas/ChatCompletionChoice"},"description":"Completion choices; each carries an index, a message, and a finish reason."},"usage":{"$ref":"#/components/schemas/ChatCompletionUsage","description":"Token usage accounting (prompt/completion/total)."}}},"ChatCompletionUsage":{"type":"object","description":"Token usage accounting (prompt/completion/total).","required":["prompt_tokens","completion_tokens","total_tokens"],"properties":{"prompt_tokens":{"type":"integer","format":"int64","description":"Prompt tokens consumed."},"completion_tokens":{"type":"integer","format":"int64","description":"Completion tokens generated."},"total_tokens":{"type":"integer","format":"int64","description":"Total tokens."}}},"ChatMessage":{"type":"object","description":"A single chat message in a completion request/response.","required":["role","content"],"properties":{"role":{"type":"string","description":"One of `system`, `user`, `assistant`.","example":"user"},"content":{"type":"string"}}},"CheckoutRequest":{"type":"object","description":"Hosted checkout request (upgrade / first paid plan).","required":["plan","success_url","cancel_url"],"properties":{"plan":{"type":"string","description":"Plan id to check out. The console sends `price_id` — accepted as\nan alias.","example":"pro"},"success_url":{"type":"string","format":"uri","description":"URL to return to after a successful payment."},"cancel_url":{"type":"string","format":"uri","description":"URL to return to when the customer cancels."},"country_code":{"type":["string","null"],"description":"Customer country code (tax calculation)."},"tenant_id":{"type":["string","null"],"description":"Tenant id; defaults to the caller's authenticated org."},"email":{"type":["string","null"],"format":"email","description":"Customer email for the provider customer record."},"interval":{"type":["string","null"],"description":"Billing interval: \"month\" (default) or \"year\"/\"annual\"."}}},"CheckoutSession":{"type":"object","description":"A hosted checkout session.","required":["session_id","url","provider"],"properties":{"session_id":{"type":"string","description":"Provider session id."},"url":{"type":"string","format":"uri","description":"Hosted payment page URL."},"provider":{"type":"string","description":"Payment provider that owns the session.","example":"razorpay"},"razorpay_key_id":{"type":["string","null"],"description":"Razorpay only: the public key id the console needs to open\nCheckout.js as an in-page modal."}}},"ComplianceCheck":{"type":"object","required":["name","passed","details"],"properties":{"name":{"type":"string"},"passed":{"type":"boolean"},"details":{"type":"string"}}},"ComplianceStatus":{"type":"object","required":["checks","passed","failed","score"],"properties":{"checks":{"type":"array","items":{"$ref":"#/components/schemas/ComplianceCheck"}},"passed":{"type":"integer","minimum":0},"failed":{"type":"integer","minimum":0},"score":{"type":"number","format":"double"}}},"ComputeDeployRequest":{"type":"object","description":"Deploy a long-running compute service (container/VM).","required":["name","image"],"properties":{"name":{"type":"string"},"image":{"type":"string"},"cpu":{"type":["integer","null"],"format":"int64"},"memory_mb":{"type":["integer","null"],"format":"int64"},"env":{"type":["object","null"],"description":"Environment variables (string → string)."},"ports":{"type":["array","null"],"items":{"type":"integer","format":"int64"}},"replicas":{"type":["integer","null"],"format":"int64"}}},"ComputeStat":{"type":"object","required":["hours_used"],"properties":{"hours_used":{"type":"number","format":"double"}}},"ComputerCreateRequest":{"type":"object","description":"Request body for creating a Computer.","required":["name"],"properties":{"name":{"type":"string","description":"Lowercase DNS label, max 63 characters. Unique per account.","example":"build-box"},"image":{"type":["string","null"],"description":"Guest image. `ubuntu24` is the only image available today.","example":"ubuntu24"},"resources":{"oneOf":[{"$ref":"#/components/schemas/ComputerResources"},{"type":"null"}]},"ssh_keys":{"type":["array","null"],"items":{"type":"string"},"description":"OpenSSH public keys authorised for `root`, one per array entry, max 32.\nOptional — `exec` and the browser terminal work without one. Send the\npublic half only (the `.pub` file); a private key is rejected.","example":["ssh-ed25519 AAAAC3Nz… you@laptop"]}}},"ComputerExecRequest":{"type":"object","description":"Request body for running a command inside a Computer.","required":["command"],"properties":{"command":{"type":"string","example":"bash"},"args":{"type":["array","null"],"items":{"type":"string"}},"cwd":{"type":["string","null"],"description":"Working directory inside the guest."},"env":{"type":"object"},"timeout_ms":{"type":["integer","null"],"format":"int64","description":"1000..600000, default 60000."}}},"ComputerExecResult":{"type":"object","description":"Result of a command executed inside a Computer.","required":["exitCode","stdout","stderr"],"properties":{"exitCode":{"type":"integer","format":"int32"},"stdout":{"type":"string"},"stderr":{"type":"string"}}},"ComputerFileRead":{"type":"object","description":"One file read out of a Computer.","required":["exists","content_b64","size"],"properties":{"exists":{"type":"boolean"},"content_b64":{"type":"string","description":"Base64-encoded contents. Empty when `exists` is false."},"size":{"type":"string","description":"Size in bytes, as a string.","example":"2"}}},"ComputerFileWrite":{"type":"object","description":"One file to write into a Computer.","required":["path","content_b64"],"properties":{"path":{"type":"string","example":"/root/hello.txt"},"content_b64":{"type":"string","description":"Base64-encoded contents."},"mode":{"type":["integer","null"],"format":"int32","description":"Unix mode, default 0644.","example":420}}},"ComputerInfo":{"type":"object","description":"A Computer as returned by create/get/list.","required":["id","name","image","status","vcpus","memoryMb","diskGb","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"type":"string"},"status":{"type":"string","description":"CREATING | RUNNING | STOPPING | STOPPED | STARTING | DELETING | FAILED","example":"RUNNING"},"statusReason":{"type":["string","null"],"description":"Human-readable reason for the current status (set on FAILED)."},"ipAddress":{"type":["string","null"],"description":"Private address inside your network. Reserved for the Computer's\nlifetime — the same address comes back after a stop/start."},"vcpus":{"type":"integer","format":"int32"},"memoryMb":{"type":"integer","format":"int32"},"diskGb":{"type":"integer","format":"int32"},"sshKeys":{"type":"array","items":{"type":"string"},"description":"The OpenSSH public keys currently authorised for `root`. Public halves\nonly — there is nothing secret to withhold here, and being able to read\nback what is installed is how you confirm a revocation took."},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}}},"ComputerResources":{"type":"object","description":"Resource shape for a Computer. Fixed at create in v1 — disks do not grow.","properties":{"vcpus":{"type":["integer","null"],"format":"int32","description":"1..16","example":2},"memory_mb":{"type":["integer","null"],"format":"int32","description":"512..32768","example":2048},"disk_gb":{"type":["integer","null"],"format":"int32","description":"5..200. Billed per GB-month for as long as the Computer exists,\nrunning or stopped.","example":20}}},"ComputerSshKeysRequest":{"type":"object","description":"Request body for replacing a Computer's authorised ssh keys.","required":["ssh_keys"],"properties":{"ssh_keys":{"type":"array","items":{"type":"string"},"description":"The complete list, max 32. Not a patch: whatever you send becomes the\nwhole of `authorized_keys`, and an empty array removes every key."}}},"ComputerWriteFilesRequest":{"type":"object","description":"Request body for writing files into a Computer. Max 64 files per call.","required":["files"],"properties":{"files":{"type":"array","items":{"$ref":"#/components/schemas/ComputerFileWrite"}}}},"ConsentRecord":{"type":"object","description":"A recorded GDPR consent decision.","required":["id","consent_type","granted","recorded_at"],"properties":{"id":{"type":"string","format":"uuid"},"consent_type":{"type":"string","example":"data_processing"},"granted":{"type":"boolean"},"ip_address":{"type":["string","null"]},"recorded_at":{"type":"string","format":"date-time"}}},"CrawlerCategory":{"type":"string","enum":["search_engine","ai_assistant","ai_coding_agent","ai_training_scraper","ai_data_provider","ai_agent","custom"]},"CrawlerPolicy":{"type":"object","required":["action"],"properties":{"action":{"$ref":"#/components/schemas/ShieldAction"},"rate_limit_per_min":{"type":["integer","null"],"format":"int64","minimum":0}}},"CreateDatabaseRequest":{"type":"object","description":"Request to create a ScalixNova database.","required":["name"],"properties":{"name":{"type":"string","description":"Display name, unique within the org.","example":"prod"},"pg_version":{"type":["string","null"],"description":"PostgreSQL major version: `\"16\"` (default), `\"17\"`, or `\"18\"`. Accepts a\nstring or number. Fixed for the life of the database — branches and\npoint-in-time restores keep this major. Unsupported values return 400\nlisting the supported set.","example":"18"},"isolation":{"type":["string","null"],"description":"Isolation tier: `\"shared\"` (default) or `\"dedicated\"` (Firecracker\nmicroVM; PostgreSQL 16 only, returns 501 where the tier isn't\nprovisioned).","example":"shared"}}},"CreateDatabaseResponse":{"type":"object","description":"Response from creating a database.","required":["id","name","pg_database","tenant_id","connection_string","status","isolation","pg_version"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"pg_database":{"type":"string"},"tenant_id":{"type":"string"},"connection_string":{"type":"string","description":"Postgres connection string (replace `YOUR_API_KEY` with an API key)."},"status":{"type":"string"},"isolation":{"type":"string"},"pg_version":{"type":"string","description":"PostgreSQL major version the database was created on.","example":"18"}}},"CreateGdprRequest":{"type":"object","required":["subject_email","request_type"],"properties":{"subject_email":{"type":"string"},"request_type":{"$ref":"#/components/schemas/GdprRequestType"},"notes":{"type":["string","null"]}}},"CreateIntegrationBody":{"type":"object","description":"Request body for `POST /v1/integrations`.","required":["provider","repo_url"],"properties":{"provider":{"type":"string","description":"One of `github`, `gitlab`, `bitbucket`."},"repo_url":{"type":"string"},"branch_filter":{"type":["string","null"]},"auto_build":{"type":["boolean","null"]},"auto_deploy":{"type":["boolean","null"]},"service_id":{"type":["string","null"]},"function_id":{"type":["string","null"],"description":"Function deploy target: every later build PUTs the fresh image onto\nthis function (drains its warm pool + re-warms the new revision).\nMutually exclusive with `service_id` — one repo deploys one thing, and\nthe tenant chooses which."},"preview_enabled":{"type":["boolean","null"]},"preview_ttl_hours":{"type":["integer","null"],"format":"int32"}}},"CreateIntegrationResponse":{"type":"object","description":"Response for `POST /v1/integrations` — the created integration plus the\nwebhook URL and secret to configure on the provider.","required":["integration","webhook_url","webhook_secret"],"properties":{"integration":{"$ref":"#/components/schemas/IntegrationJson"},"webhook_url":{"type":"string"},"webhook_secret":{"type":"string"}}},"CreateLbRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"strategy":{"$ref":"#/components/schemas/Strategy"},"backends":{"type":"array","items":{"$ref":"#/components/schemas/AddBackendRequest"}},"health_check":{"oneOf":[{"$ref":"#/components/schemas/HealthCheckConfig"},{"type":"null"}]}}},"CreateRuleRequest":{"type":"object","required":["name","pattern","action"],"properties":{"name":{"type":"string"},"pattern":{"$ref":"#/components/schemas/WafPattern"},"action":{"$ref":"#/components/schemas/WafAction"},"priority":{"type":"integer","format":"int32","minimum":0},"enabled":{"type":"boolean","description":"SEC-6: enable/disable a rule. Defaults to enabled on create; on update,\nthis is what makes the toggle actually work (the old update ignored it)."}}},"CreateVpcBody":{"type":"object","description":"Request body for `POST /v1/vpc`. Mirrors `scalix_vpc::CreateVpcRequest`.\nDocumentation-only: the handler deserializes the external type directly, so\nthese fields are read by utoipa, not by runtime code.","required":["name","cidr"],"properties":{"name":{"type":"string"},"cidr":{"type":"string","description":"CIDR block for the VPC, e.g. `10.0.0.0/16`."}}},"CustomRule":{"type":"object","description":"Customer-defined user-agent rule. Takes precedence over the built-in\ncrawler database so customers can police bots we don't know about yet —\nor override how a known bot is matched.","required":["id","name","ua_pattern","policy","created_at"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"ua_pattern":{"type":"string","description":"Case-insensitive substring matched against the User-Agent header."},"policy":{"$ref":"#/components/schemas/CrawlerPolicy"},"created_at":{"type":"string","format":"date-time"}}},"CustomRuleRequest":{"allOf":[{"$ref":"#/components/schemas/CrawlerPolicy"},{"type":"object","required":["name","ua_pattern"],"properties":{"name":{"type":"string"},"ua_pattern":{"type":"string","description":"Case-insensitive substring matched against the User-Agent header."}}}],"description":"Request body for `POST /v1/shield/custom` — a customer-defined UA rule.\nThe `CrawlerPolicy` fields (`action`, `rate_limit_per_min`) are flattened\ninto the top level alongside `name` and `ua_pattern`."},"DataSubjectRequest":{"type":"object","required":["id","tenant_id","subject_email","request_type","status","created_at"],"properties":{"id":{"type":"string","format":"uuid"},"tenant_id":{"type":"string"},"subject_email":{"type":"string"},"request_type":{"$ref":"#/components/schemas/GdprRequestType"},"status":{"$ref":"#/components/schemas/RequestStatus"},"notes":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"}}},"DatabaseJson":{"type":"object","description":"A ScalixNova database record.","required":["id","name","status","isolation","pg_version"],"properties":{"id":{"type":"string","description":"Database id (UUID)."},"name":{"type":"string","description":"Display name."},"pg_database":{"type":["string","null"],"description":"Physical PostgreSQL database name (`db_<hex>`)."},"tenant_id":{"type":["string","null"],"description":"Tenant id backing this database on the compute plane."},"status":{"type":"string","description":"`active` or `deleting` (soft-deleted, inside the recovery grace window).","example":"active"},"created_at":{"type":["string","null"],"description":"RFC 3339 creation time."},"isolation":{"type":"string","description":"Isolation tier: `shared` or `dedicated`.","example":"shared"},"pg_version":{"type":"string","description":"PostgreSQL major version this database runs (`16`, `17`, or `18`).","example":"16"},"deleted_at":{"type":["string","null"],"description":"Soft-delete timestamp, when `status` is `deleting`."}}},"DdosStats":{"type":"object","required":["global_rps","tracked_ips","blocked_ips","threshold_rps","global_threshold"],"properties":{"global_rps":{"type":"integer","format":"int64","minimum":0},"tracked_ips":{"type":"integer","minimum":0},"blocked_ips":{"type":"array","items":{"type":"string"}},"threshold_rps":{"type":"integer","format":"int64","minimum":0},"global_threshold":{"type":"integer","format":"int64","minimum":0}}},"DeletedResponse":{"type":"object","description":"Standard `{ \"deleted\": true }` acknowledgement.","required":["deleted"],"properties":{"deleted":{"type":"boolean"}}},"DomainInstructions":{"type":"object","description":"DNS setup steps returned when a domain is added.","required":["step_1","step_2","step_3","step_4"],"properties":{"step_1":{"type":"string"},"step_2":{"type":"string"},"step_3":{"type":"string"},"step_4":{"type":"string"}}},"DomainJson":{"type":"object","description":"A custom domain attached to a project, with verification + SSL state.","required":["id","project_id","domain","domain_type","status","verification_token","ssl_status","ssl_expires_at","ssl_issued_at","primary_domain","created_at","updated_at"],"properties":{"id":{"type":"string"},"project_id":{"type":"string"},"domain":{"type":"string"},"domain_type":{"type":"string"},"status":{"type":"string"},"verification_token":{"type":"string"},"ssl_status":{"type":"string"},"ssl_expires_at":{"type":"string"},"ssl_issued_at":{"type":"string"},"ssl_error":{"type":["string","null"],"description":"Last cert-issuance failure reason (absent = none). Lets the console show\n\"DNS doesn't point to our edge\" instead of a silent stuck 'none'/'failed'."},"primary_domain":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"cname_target":{"type":["string","null"]},"run_service":{"type":["string","null"],"description":"Run service this domain serves (absent = the project's API surface)."},"storage_bucket":{"type":["string","null"]},"function_name":{"type":["string","null"],"description":"Function this domain serves (absent = not a function target)."},"edge_ip":{"type":["string","null"],"description":"Gateway IP for apex A-record setup (absent if not configured)."}}},"EmailAddDomainRequest":{"type":"object","description":"The domain to add to the org's sending domains.","required":["domain"],"properties":{"domain":{"type":"string","description":"Domain to add.","example":"mail.example.com"}}},"EmailDomain":{"type":"object","description":"A sending domain owned by the org, with the DNS records it needs.","required":["id","domain","status"],"properties":{"id":{"type":"string","description":"Domain id."},"domain":{"type":"string","description":"The domain itself.","example":"mail.example.com"},"status":{"type":"string","description":"Verification state of the DNS records.","example":"pending"},"dns_records":{"type":["object","null"],"description":"DNS records that must exist for the domain to verify."},"delivery_enabled":{"type":["boolean","null"],"description":"Whether this org may actually send through the domain. Verification\nalone is not sufficient: bring-your-own delivery is a separate switch."}}},"EmailSendRawRequest":{"type":"object","description":"A one-off email with its body supplied inline.","required":["to","subject","html"],"properties":{"to":{"type":"string","description":"Recipient address.","example":"user@example.com"},"subject":{"type":"string","description":"Subject line.","example":"Your receipt"},"html":{"type":"string","description":"HTML body.","example":"<p>Thanks for your order.</p>"}}},"EmailSendResponse":{"type":"object","description":"The accepted-for-delivery receipt returned by both send endpoints.","required":["id","status","to"],"properties":{"id":{"type":"string","description":"Message id, used to correlate later delivery events.","example":"01J8Z4T2QK9V3H"},"status":{"type":"string","description":"Delivery state at the time of the response.","example":"queued"},"to":{"type":"string","description":"Recipient the message was accepted for.","example":"user@example.com"},"template":{"type":["string","null"],"description":"Template used, echoed back on the templated send."}}},"EmailSendTxRequest":{"type":"object","description":"A templated transactional email to send.","required":["template","to"],"properties":{"template":{"type":"string","description":"Name of the template to render.","example":"order_confirmation"},"to":{"type":"string","description":"Recipient address.","example":"user@example.com"},"data":{"type":["object","null"],"description":"Variables substituted into the template."}}},"EnvVar":{"type":"object","description":"A project environment variable (secret values are masked).","required":["id","key","value","is_secret","created_at","updated_at"],"properties":{"id":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"},"is_secret":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"ErrorResponse":{"type":"object","description":"Standard error envelope every endpoint returns. Mirrors the body produced by\n`ApiError`'s `IntoResponse` in `server.rs` (`ApiError` itself can't derive\n`ToSchema` — it holds a `StatusCode`). Keep the field set in sync.","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable error message.","example":"Authentication required"},"code":{"type":"string","description":"Stable machine-readable code, e.g. `AUTH_FAILED`.","example":"AUTH_FAILED"},"request_id":{"type":["string","null"],"description":"Correlation id for support."},"docs_url":{"type":["string","null"],"description":"Link to the relevant error docs."},"field":{"type":["string","null"],"description":"Offending field, for validation errors."}}},"FunctionDeployRequest":{"type":"object","description":"Deploy a serverless function.","required":["name","runtime","image_ref"],"properties":{"name":{"type":"string"},"runtime":{"type":"string","description":"One of `node`, `python`, `go`, `rust`.","example":"node"},"image_ref":{"type":"string"},"entry_point":{"type":["string","null"]},"handler":{"type":["string","null"]},"env":{"type":["object","null"],"description":"Environment variables for the function (string → string)."},"timeout_ms":{"type":["integer","null"],"format":"int64"},"memory_mb":{"type":["integer","null"],"format":"int64"},"cron_expression":{"type":["string","null"]},"http_trigger":{"type":["boolean","null"]}}},"FunctionsStat":{"type":"object","required":["invocations"],"properties":{"invocations":{"type":"number","format":"double"}}},"GdprRequestType":{"type":"string","enum":["export","erasure","rectification","access"]},"GlitchRuleCreate":{"type":"object","description":"A tenant-authored glitch rule creation request (doc-only mirror of the\nrouter's `CreateGlitchRuleBody`).","required":["action","match_statuses"],"properties":{"action":{"type":"string","description":"`ignore` (never a glitch for my app) or `track` (record under my label)."},"label":{"type":["string","null"],"description":"Required for `track`: the tenant's own category name (becomes the group key, 1-64 chars)."},"hint":{"type":["string","null"],"description":"Optional: the tenant's own remediation note shown with the group (max 280 chars)."},"match_statuses":{"type":"array","items":{"type":"integer","format":"int32"},"description":"HTTP status codes this rule matches (100-599, 1-32 codes)."},"path_prefix":{"type":["string","null"],"description":"Optional path prefix the rule is scoped to (must start with `/`, max 256 chars)."},"host":{"type":["string","null"],"description":"Optional exact host the rule is scoped to (bare hostname, max 253 chars)."}}},"HealthCheckConfig":{"type":"object","required":["interval_secs","timeout_secs","path","expected_status"],"properties":{"interval_secs":{"type":"integer","format":"int64","minimum":0},"timeout_secs":{"type":"integer","format":"int64","minimum":0},"path":{"type":"string"},"expected_status":{"type":"integer","format":"int32","minimum":0}}},"InstallationJson":{"type":"object","description":"A GitHub App installation linked to a project.","required":["id","project_id","installation_id","account_login","account_type","status","created_at","updated_at"],"properties":{"id":{"type":"string"},"project_id":{"type":"string"},"installation_id":{"type":"integer","format":"int64"},"account_login":{"type":"string"},"account_type":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"IntegrationJson":{"type":"object","description":"A source-control integration (GitHub/GitLab/Bitbucket) attached to a project.","required":["id","project_id","provider","repo_url","branch_filter","auto_build","auto_deploy","status","preview_enabled","preview_ttl_hours","created_at","updated_at"],"properties":{"id":{"type":"string"},"project_id":{"type":"string"},"provider":{"type":"string"},"repo_url":{"type":"string"},"branch_filter":{"type":"string"},"auto_build":{"type":"boolean"},"auto_deploy":{"type":"boolean"},"status":{"type":"string"},"service_id":{"type":["string","null"]},"function_id":{"type":["string","null"]},"preview_enabled":{"type":"boolean"},"preview_ttl_hours":{"type":"integer","format":"int32"},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"IntegrationResponse":{"type":"object","description":"Response for `GET`/`PUT /v1/integrations/{id}`.","required":["integration"],"properties":{"integration":{"$ref":"#/components/schemas/IntegrationJson"}}},"IpRangesRequest":{"type":"object","description":"Request body for `PUT /v1/shield/crawlers/{id}/ip-ranges`.","required":["ranges"],"properties":{"ranges":{"type":"array","items":{"type":"string"},"description":"IP addresses or CIDR ranges used to verify the crawler's source IP."}}},"KeyUsage":{"type":"object","description":"One of the org's API keys with its real, IAM-tracked metadata.\n\nNote: per-key *request counts* are not tracked — metering is keyed by\norg/project (see docs/IDENTITY.md), not by individual key — so this returns\nthe authoritative key metadata IAM holds (incl. `last_used_at`) rather than a\nfabricated request total. Org/project usage totals live at `/v1/usage/{id}`.","required":["key_id","key_name","key_prefix"],"properties":{"key_id":{"type":"string","description":"API key id (UUID)."},"key_name":{"type":"string","description":"Human-friendly key name."},"key_prefix":{"type":"string","description":"Non-secret key prefix, e.g. `scalix_sk_ab12`."},"last_used_at":{"type":["string","null"],"description":"RFC3339 timestamp of the key's last use, or null if never used."}}},"KeyUsageDetail":{"type":"object","description":"Response for `GET /v1/usage/keys/{key_id}` — metadata for one key.","required":["key_id","key_name","key_prefix"],"properties":{"key_id":{"type":"string"},"key_name":{"type":"string"},"key_prefix":{"type":"string"},"last_used_at":{"type":["string","null"],"description":"RFC3339 timestamp of the key's last use, or null if never used."}}},"KeysUsageResponse":{"type":"object","description":"Response for `GET /v1/usage/keys` — the org's API keys and their metadata.","required":["keys"],"properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/KeyUsage"}}}},"KvDelRequest":{"type":"object","description":"Body for `/v1/kv/del` — one or more keys to delete (batch delete).\n\nMatches the implementation (`crates/kvstore/src/api.rs` `DelRequest`), which\ntakes a `keys` array, not a single `key`.","required":["keys"],"properties":{"keys":{"type":"array","items":{"type":"string"}}}},"KvKeyRequest":{"type":"object","description":"Body for `/v1/kv/get`, `/v1/kv/exists` — a single key.","required":["key"],"properties":{"key":{"type":"string"}}},"KvKeysRequest":{"type":"object","description":"Body for `/v1/kv/keys` — list keys matching an optional glob pattern.","properties":{"pattern":{"type":["string","null"],"description":"Glob pattern; defaults to `*` (all keys) when omitted.","example":"user:*"}}},"KvSetRequest":{"type":"object","description":"Set a key in the key-value store. The downstream kvstore accepts a JSON\n`value` of any shape; `ttl` is in seconds and optional.","required":["key","value"],"properties":{"key":{"type":"string"},"value":{"type":"object"},"ttl":{"type":["integer","null"],"format":"int64","description":"Optional time-to-live in seconds."}}},"ListDatabasesResponse":{"type":"object","description":"Databases in the project.","required":["databases"],"properties":{"databases":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseJson"}},"delete_grace_days":{"type":["integer","null"],"format":"int64","description":"Days a soft-deleted database stays restorable."}}},"ListDomainsResponse":{"type":"object","description":"Response for `GET /v1/domains` — all custom domains for the project.","required":["domains"],"properties":{"domains":{"type":"array","items":{"$ref":"#/components/schemas/DomainJson"}}}},"ListEnvResponse":{"type":"object","description":"Response for `GET /v1/env` — all project environment variables.","required":["variables"],"properties":{"variables":{"type":"array","items":{"$ref":"#/components/schemas/EnvVar"}}}},"ListInstallationsResponse":{"type":"object","description":"Response for `GET /v1/integrations/github/installations`.","required":["installations"],"properties":{"installations":{"type":"array","items":{"$ref":"#/components/schemas/InstallationJson"}}}},"ListIntegrationsResponse":{"type":"object","description":"Response for `GET /v1/integrations`.","required":["integrations"],"properties":{"integrations":{"type":"array","items":{"$ref":"#/components/schemas/IntegrationJson"}}}},"LoadBalancerInfo":{"type":"object","required":["id","name","strategy","backends","created_at"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"strategy":{"$ref":"#/components/schemas/Strategy"},"backends":{"type":"array","items":{"$ref":"#/components/schemas/BackendInfo"}},"created_at":{"type":"string","format":"date-time"}}},"MeIdentity":{"type":"object","description":"Token identity (key, type, tenancy, creator).","required":["key_id","token_type","org_id","created_by"],"properties":{"key_id":{"type":"string"},"token_type":{"type":"string"},"org_id":{"type":"string"},"project_id":{"type":["string","null"]},"created_by":{"type":"string"}}},"MeLimits":{"type":"object","description":"Plan-derived limits (advisory — see `api_key_limit_for_plan`/`rate_limit_for_plan`).","required":["plan","rate_limit_rps","api_keys_max","connected_apps_max"],"properties":{"plan":{"type":"string"},"rate_limit_rps":{"type":"integer","format":"int32","minimum":0},"api_keys_max":{"type":"integer","format":"int64"},"connected_apps_max":{"type":"integer","format":"int64","description":"OAuth-granted connected apps (ChatGPT, Claude, an IDE …). A separate pool\nfrom `api_keys_max` — see `plan_limits::connected_apps_for_plan`. Reported\nso the console reads the limit from the server that enforces it, rather\nthan from a client-side constant that can drift out of step."}}},"MePermissions":{"type":"object","description":"Effective permissions for the caller's token.","required":["role","scopes","can_create_keys","can_create_projects"],"properties":{"role":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"can_create_keys":{"type":"boolean"},"can_create_projects":{"type":"boolean"}}},"MeResponse":{"type":"object","description":"Response for `GET /v1/me` — identity, permissions, available MCP tools, limits.","required":["identity","permissions","tools","limits"],"properties":{"identity":{"$ref":"#/components/schemas/MeIdentity"},"permissions":{"$ref":"#/components/schemas/MePermissions"},"tools":{"type":"array","items":{"type":"string"}},"limits":{"$ref":"#/components/schemas/MeLimits"}}},"ProvisionSslResponse":{"type":"object","description":"Response for `POST /v1/domains/{id}/ssl`.","required":["domain","ssl_status","message"],"properties":{"domain":{"type":"string"},"ssl_status":{"type":"string"},"message":{"type":"string"}}},"RecordConsentRequest":{"type":"object","description":"Record a single consent decision (POST `/v1/auth/user/consent`).","required":["consent_type","granted"],"properties":{"consent_type":{"type":"string"},"granted":{"type":"boolean"}}},"RequestStatus":{"type":"string","enum":["pending","in_progress","completed","rejected"]},"RunServiceDeployRequest":{"type":"object","description":"A Scalix Run service to deploy.","required":["name","image_ref"],"properties":{"name":{"type":"string","description":"Service name, unique within the project.","example":"api"},"image_ref":{"type":"string","description":"Container image to run.","example":"registry.scalix.world/acme/api:1.4.0"},"port":{"type":["integer","null"],"format":"int32","description":"Port the app listens on inside the instance. Default 8080.","example":8080},"env":{"type":["object","null"],"description":"Environment variables."},"memory_mb":{"type":["integer","null"],"format":"int32","description":"Memory per instance in MB. Default 256, minimum 128.","example":512},"vcpus":{"type":["integer","null"],"format":"int32","description":"vCPUs per instance. Default 1.","example":1},"min_instances":{"type":["integer","null"],"format":"int32","description":"Minimum instances kept warm. Default 0 (scale to zero).","example":0},"max_instances":{"type":["integer","null"],"format":"int32","description":"Maximum instances. Default 10.","example":10},"target_concurrency":{"type":["integer","null"],"format":"int32","description":"Concurrent requests per instance before scaling out. Default 50.","example":50},"scale_down_delay_secs":{"type":["integer","null"],"format":"int32","description":"Idle seconds before scaling in. Default 300.","example":300},"health_check_path":{"type":["string","null"],"description":"HTTP path for the readiness probe. Omit for the default check that the\napp is listening on `port`.","example":"/healthz"},"timeout_secs":{"type":["integer","null"],"format":"int32","description":"Per-request timeout in seconds. Default 300.","example":300},"rollout_strategy":{"type":["string","null"],"description":"`instant`, `health_gated` (default), or `canary`.","example":"health_gated"},"volumes":{"type":["object","null"],"description":"Persistent volumes. Attaching one pins the service to a single instance\nand the `instant` strategy."}}},"RunServiceUpdateRequest":{"type":"object","description":"Changes to apply to an existing Scalix Run service.\n\nEvery field is optional; omitted fields are left as-is. Changing\n`image_ref` is what triggers a new revision and a rollout.","properties":{"image_ref":{"type":["string","null"]},"env":{"type":["object","null"]},"memory_mb":{"type":["integer","null"],"format":"int32","example":512},"vcpus":{"type":["integer","null"],"format":"int32"},"min_instances":{"type":["integer","null"],"format":"int32"},"max_instances":{"type":["integer","null"],"format":"int32"},"target_concurrency":{"type":["integer","null"],"format":"int32"},"scale_down_delay_secs":{"type":["integer","null"],"format":"int32"},"health_check_path":{"type":["string","null"]},"timeout_secs":{"type":["integer","null"],"format":"int32"},"rollout_strategy":{"type":["string","null"],"description":"Strategy for the rollout this update triggers.","example":"health_gated"},"rollout_stages":{"type":["object","null"],"description":"Canary stages, e.g. `[{\"pct\":10,\"soak_secs\":60}]`."},"ready_threshold":{"type":["integer","null"],"format":"int32","description":"Instances that must pass the probe before the revision is promoted.","example":3},"gate_deadline_secs":{"type":["integer","null"],"format":"int32","description":"Seconds the new revision has to pass its readiness gate before it is\nrolled back to the previous revision. Raise it for apps with a slow cold\nstart (model loading, large runtimes) - a revision that boots fine but\nwarms up slowly is otherwise reverted, leaving the older revision\nserving with its own resource settings.","example":300}}},"SandboxCommandRequest":{"type":"object","description":"Request body for running a command inside a sandbox.","required":["cmd"],"properties":{"cmd":{"type":"string","example":"node"},"args":{"type":["array","null"],"items":{"type":"string"}},"cwd":{"type":["string","null"],"description":"Working directory inside the guest."},"env":{"type":"object"},"detached":{"type":["boolean","null"],"description":"Run without waiting for completion."}}},"SandboxCommandResult":{"type":"object","description":"Result of a synchronous command execution.","required":["exit_code","stdout","stderr","duration_ms"],"properties":{"exit_code":{"type":"integer","format":"int32"},"stdout":{"type":"string"},"stderr":{"type":"string"},"duration_ms":{"type":"integer","format":"int64"}}},"SandboxCreateRequest":{"type":"object","description":"Request body for creating an ephemeral sandbox.","properties":{"runtime":{"type":["string","null"],"description":"Runtime image. `node22` is available today; other values are rolling\nout and fail placement until their images ship.","example":"node22"},"resources":{"type":"object","description":"Resource shape. Defaults: 1 vCPU, 512 MB memory, 5 GB disk."},"timeout_ms":{"type":["integer","null"],"format":"int64","description":"Hard lifetime in milliseconds (60000..86400000, default 300000). The\nsandbox also stops earlier at its idle timeout."},"ports":{"type":["array","null"],"items":{"type":"integer","format":"int32","minimum":0},"description":"Guest ports to expose."},"source":{"type":"object","description":"`{type: \"git\", url, branch?}` clones a repository into the sandbox."},"env":{"type":"object","description":"Environment variables for the guest."}}},"SandboxExtendRequest":{"type":"object","description":"Request body for extending a sandbox's hard deadline.","required":["duration_ms"],"properties":{"duration_ms":{"type":"integer","format":"int64","description":"Milliseconds to add to the current expiry.","example":600000}}},"SandboxInfo":{"type":"object","description":"A sandbox as returned by create/get/list.","required":["id","runtime","status","vcpus","memory_mb","disk_gb","expires_at"],"properties":{"id":{"type":"string"},"runtime":{"type":"string"},"status":{"type":"string","description":"PROVISIONING | RUNNING | STOPPING | STOPPED | FAILED | EXPIRED","example":"RUNNING"},"status_reason":{"type":["string","null"],"description":"Human-readable reason for the current status (set on FAILED and\nidle-stop transitions)."},"vcpus":{"type":"integer","format":"int32"},"memory_mb":{"type":"integer","format":"int32"},"disk_gb":{"type":"integer","format":"int32"},"expires_at":{"type":"string"}}},"SandboxWriteFilesRequest":{"type":"object","description":"Request body for writing files into a sandbox. Writable roots inside the\nguest are `/app`, `/scalix`, `/build`, and `/tmp`.","required":["files"],"properties":{"files":{"type":"array","items":{"type":"object"},"description":"Files to write: `[{path, content}]`."}}},"ScopeConfig":{"type":"object","properties":{"enabled":{"type":"boolean"},"inject_noai_headers":{"type":"boolean","description":"Adds `X-Robots-Tag: noai, noimageai` to proxied responses."},"tdm_reservation":{"type":"boolean","description":"Adds `tdm-reservation: 1` (EU DSM Directive text-and-data-mining opt-out)."},"block_impersonators":{"type":"boolean","description":"Block crawlers whose source IP fails verification against configured\nranges. Off by default: stale ranges must not break legitimate bots."},"category_defaults":{"type":"object","description":"Per-category default action, keyed by crawler category."}}},"SetEnvBody":{"type":"object","description":"Request body for `POST /v1/env` — a single project environment variable.\nFields are read by serde + utoipa; the 501-stub handlers ignore the body.","required":["key","value"],"properties":{"key":{"type":"string"},"value":{"type":"string"},"is_secret":{"type":["boolean","null"],"description":"Store the value as a write-only secret (masked on read)."}}},"ShieldAction":{"type":"string","enum":["allow","block","rate_limit"]},"SignInRequest":{"type":"object","description":"Email/password login payload.","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"}}},"SignUpRequest":{"type":"object","description":"New-account signup payload.","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8},"data":{"type":["object","null"],"description":"Arbitrary user metadata to attach to the account."},"captcha_token":{"type":["string","null"]}}},"SpendingCapRequest":{"type":"object","description":"Spending cap configuration.","required":["monthly_cap_cents"],"properties":{"monthly_cap_cents":{"type":"integer","format":"int64","description":"Monthly spend cap, in cents.","example":50000},"alert_threshold_pct":{"type":["integer","null"],"format":"int32","description":"Alert threshold as a percentage of the cap (e.g. 80 = alert at\n80%)."},"hard_limit":{"type":["boolean","null"],"description":"Hard-limit the org when the cap is reached (vs alert only)."}}},"SqlColumnInfo":{"type":"object","description":"One column of a SQL result set.","required":["name","type_oid","type_name"],"properties":{"name":{"type":"string","description":"Column name.","example":"id"},"type_oid":{"type":"integer","format":"int32","description":"PostgreSQL type OID.","example":23},"type_name":{"type":"string","description":"PostgreSQL type name.","example":"int4"}}},"SqlQueryCost":{"type":"object","description":"Per-query resource cost breakdown.","required":["compute_ms","pages_read","bytes_transferred","estimated_usd"],"properties":{"compute_ms":{"type":"number","format":"double","description":"Compute time consumed, in milliseconds."},"pages_read":{"type":"integer","format":"int64","description":"Pages read to serve the query.","minimum":0},"bytes_transferred":{"type":"integer","format":"int64","description":"Bytes transferred to the client.","minimum":0},"estimated_usd":{"type":"number","format":"double","description":"Estimated cost in USD."}}},"SqlRequest":{"type":"object","description":"A parameterized SQL query to execute against the tenant's database.","required":["query"],"properties":{"query":{"type":"string","description":"The SQL statement, with `$1`, `$2`, … placeholders for params.","example":"SELECT * FROM users WHERE id = $1"},"params":{"type":["object","null"],"description":"Positional bind parameters for the placeholders, in order."},"timeline_id":{"type":["string","null"],"description":"Branch timeline to run the query against, as returned by\n`scalix_db_branch_create` (optionally in its `db_<timeline>` connection-string\nform). Omit for the project's primary. A timeline that is not a branch of\nthis project is rejected — it never falls back to the primary (F17)."}}},"SqlResponse":{"type":"object","description":"Result set returned by a SQL query. Matches the wire shape produced by\n`http.rs::SqlResponse` - `columns` entries are objects (name + Postgres\ntype), not bare strings.","required":["columns","rows","row_count","command","duration_ms","cost"],"properties":{"columns":{"type":"array","items":{"$ref":"#/components/schemas/SqlColumnInfo"},"description":"Result-set columns, in result order."},"rows":{"type":"object","description":"Rows; each row is an array of cell values aligned to `columns`."},"row_count":{"type":"integer","format":"int64","description":"Number of rows returned (or affected)."},"command":{"type":"string","description":"The SQL command tag (e.g. `SELECT`, `INSERT`).","example":"SELECT"},"duration_ms":{"type":"number","format":"double","description":"Server-side execution time in milliseconds."},"cost":{"$ref":"#/components/schemas/SqlQueryCost","description":"Resource cost of this query."}}},"StatsResponse":{"type":"object","description":"Response for `GET /v1/user/stats`.","required":["user_id","period","services"],"properties":{"user_id":{"type":"string"},"period":{"type":"string"},"services":{"$ref":"#/components/schemas/StatsServices"}}},"StatsServices":{"type":"object","description":"Per-service usage breakdown.","required":["ai","storage","compute","bandwidth","functions"],"properties":{"ai":{"$ref":"#/components/schemas/AiStat"},"storage":{"$ref":"#/components/schemas/StorageStat"},"compute":{"$ref":"#/components/schemas/ComputeStat"},"bandwidth":{"$ref":"#/components/schemas/BandwidthStat"},"functions":{"$ref":"#/components/schemas/FunctionsStat"}}},"StorageStat":{"type":"object","required":["gb_used"],"properties":{"gb_used":{"type":"number","format":"double"}}},"Strategy":{"type":"string","enum":["round_robin","least_connections","weighted_round_robin","ip_hash"]},"TaxInfoRequest":{"type":"object","description":"Tax-info update (GST/VAT registration details).","required":["tax_type","tax_id","country_code"],"properties":{"tax_type":{"type":"string","description":"Tax type (\"gst\", \"vat\", …).","example":"gst"},"tax_id":{"type":"string","description":"Tax identification number.","example":"27AABCU9603R1ZM"},"country_code":{"type":"string","description":"ISO country code.","example":"IN"},"business_name":{"type":["string","null"],"description":"Registered business name."},"state_code":{"type":["string","null"],"description":"State/province code."},"vat_id":{"type":["string","null"],"description":"VAT number (EU)."},"reverse_charge":{"type":"boolean","description":"Reverse-charge applies (B2B intra-EU)."},"export_lut":{"type":"boolean","description":"Export LUT applies (India exports)."},"exempt":{"type":"boolean","description":"The org is tax-exempt."}}},"TokenResponse":{"type":"object","description":"A short-lived GitHub installation access token.","required":["token","expires_at"],"properties":{"token":{"type":"string"},"expires_at":{"type":"string"}}},"UpdateGdprStatusBody":{"type":"object","required":["status"],"properties":{"status":{"$ref":"#/components/schemas/RequestStatus","description":"One of: pending, in_progress, completed, rejected."}}},"UpdateIntegrationBody":{"type":"object","description":"Request body for `PUT /v1/integrations/{id}`.","properties":{"branch_filter":{"type":["string","null"]},"auto_build":{"type":["boolean","null"]},"auto_deploy":{"type":["boolean","null"]},"service_id":{"type":["string","null"]},"function_id":{"type":["string","null"],"description":"Tri-state like the functions crate's `cron_expression`: absent = keep\nthe current link, null = clear it (the console's \"None\" option), and a\nstring = set it. A plain Option cannot tell \"clear\" from \"not sent\",\nwhich made an un-picked function target impossible to remove.\nserde's derive alone is not enough: with a plain\n`Option<Option<String>>`, JSON `null` also deserializes to `None`\n(reads as \"absent\"), so the custom deserializer below lifts a present\nfield — null included — into the outer Some."},"preview_enabled":{"type":["boolean","null"]},"preview_ttl_hours":{"type":["integer","null"],"format":"int32"},"status":{"type":["string","null"]}}},"User":{"type":"object","description":"An end-user account.","required":["id","email","created_at","updated_at","user_metadata","app_metadata"],"properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"phone":{"type":["string","null"]},"email_confirmed_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"last_sign_in_at":{"type":["string","null"],"format":"date-time"},"user_metadata":{"type":"object"},"app_metadata":{"type":"object"}}},"UserInfo":{"type":"object","description":"Account profile for the caller (`GET /v1/user/info`). Fields after `status`\nare present only when the user record exists.","required":["id","plan","status"],"properties":{"id":{"type":"string"},"email":{"type":["string","null"],"description":"Account email; `null` for an unknown user."},"name":{"type":["string","null"],"description":"Display name; `null` if unset/unknown."},"plan":{"type":"string"},"status":{"type":"string"},"login_count":{"type":["integer","null"],"format":"int64"},"created_at":{"type":["string","null"]},"last_login_at":{"type":["string","null"]}}},"VectorEntry":{"type":"object","description":"A single vector entry for upsert.","required":["id","embedding"],"properties":{"id":{"type":"string"},"embedding":{"type":"array","items":{"type":"number","format":"double"},"description":"The embedding values."},"metadata":{"type":["object","null"]}}},"VectorSearchRequest":{"type":"object","description":"A nearest-neighbour vector search.","required":["collection","query_vector"],"properties":{"collection":{"type":"string"},"query_vector":{"type":"array","items":{"type":"number","format":"double"},"description":"The query embedding."},"top_k":{"type":["integer","null"],"format":"int64","description":"Number of nearest neighbours to return."},"filter":{"type":["object","null"],"description":"Optional metadata filter."}}},"VectorUpsertRequest":{"type":"object","description":"Upsert a batch of vectors into a collection.","required":["collection","entries"],"properties":{"collection":{"type":"string"},"entries":{"type":"array","items":{"$ref":"#/components/schemas/VectorEntry"}}}},"VerifyDomainResponse":{"type":"object","description":"Response for `POST /v1/domains/{id}/verify`.","required":["verified","domain","status"],"properties":{"verified":{"type":"boolean"},"domain":{"type":"string"},"status":{"type":"string"}}},"VpcConfigResponse":{"type":"object","description":"The configuration file for a VPC.","required":["config"],"properties":{"config":{"type":"string","description":"The rendered VPN client configuration."}}},"VpcJson":{"type":"object","description":"A VPC. Mirrors `scalix_vpc::Vpc`.","required":["id","tenant_id","name","cidr","private_key","public_key","listen_port","status","created_at"],"properties":{"id":{"type":"string"},"tenant_id":{"type":"string"},"name":{"type":"string"},"cidr":{"type":"string"},"private_key":{"type":"string"},"public_key":{"type":"string"},"listen_port":{"type":"integer","format":"int32","minimum":0},"endpoint":{"type":["string","null"]},"status":{"type":"string","description":"One of `provisioning`, `active`, `degraded`, `deleting`."},"created_at":{"type":"string"}}},"VpcPeerJson":{"type":"object","description":"A peer in a VPC. Mirrors `scalix_vpc::VpcPeer`.","required":["id","vpc_id","name","public_key","allowed_ips","persistent_keepalive","created_at"],"properties":{"id":{"type":"string"},"vpc_id":{"type":"string"},"name":{"type":"string"},"public_key":{"type":"string"},"allowed_ips":{"type":"array","items":{"type":"string"}},"endpoint":{"type":["string","null"]},"persistent_keepalive":{"type":"integer","format":"int32","minimum":0},"created_at":{"type":"string"}}},"WafAction":{"type":"string","enum":["block","log","challenge","rate_limit"]},"WafEvent":{"type":"object","required":["id","rule_id","rule_name","action","source_ip","path","reason","timestamp"],"properties":{"id":{"type":"string","format":"uuid"},"tenant_id":{"type":"string"},"rule_id":{"type":"string","format":"uuid"},"rule_name":{"type":"string"},"action":{"$ref":"#/components/schemas/WafAction"},"source_ip":{"type":"string"},"path":{"type":"string"},"reason":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"WafPattern":{"oneOf":[{"type":"object","required":["addresses","type"],"properties":{"addresses":{"type":"array","items":{"type":"string"}},"type":{"type":"string","enum":["ip_block"]}}},{"type":"object","required":["pattern","type"],"properties":{"pattern":{"type":"string"},"type":{"type":"string","enum":["path_match"]}}},{"type":"object","required":["name","pattern","type"],"properties":{"name":{"type":"string"},"pattern":{"type":"string"},"type":{"type":"string","enum":["header_match"]}}},{"type":"object","required":["max_bytes","type"],"properties":{"max_bytes":{"type":"integer","minimum":0},"type":{"type":"string","enum":["body_size_limit"]}}},{"type":"object","required":["window_secs","max_requests","type"],"properties":{"window_secs":{"type":"integer","format":"int64","minimum":0},"max_requests":{"type":"integer","format":"int64","minimum":0},"type":{"type":"string","enum":["rate_limit"]}}},{"type":"object","required":["countries","type"],"properties":{"countries":{"type":"array","items":{"type":"string"}},"type":{"type":"string","enum":["geo_block"]}}},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["sql_injection"]}}},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["xss"]}}}]},"WafRule":{"type":"object","required":["id","name","pattern","action","priority","enabled"],"properties":{"id":{"type":"string","format":"uuid"},"tenant_id":{"type":"string","description":"Owning project/tenant. SEC-2: rules and their enforcement are scoped to\nthis — a rule is only ever applied to its own tenant's traffic, and only\nits owner can see/update/delete it."},"name":{"type":"string"},"pattern":{"$ref":"#/components/schemas/WafPattern"},"action":{"$ref":"#/components/schemas/WafAction"},"priority":{"type":"integer","format":"int32","minimum":0},"enabled":{"type":"boolean"}}},"WafStats":{"type":"object","required":["total_requests","blocked_requests","blocked_24h","logged_requests","top_blocked_ips","top_rules","rules_count"],"properties":{"total_requests":{"type":"integer","format":"int64","minimum":0},"blocked_requests":{"type":"integer","format":"int64","minimum":0},"blocked_24h":{"type":"integer","format":"int64","minimum":0},"logged_requests":{"type":"integer","format":"int64","minimum":0},"top_blocked_ips":{"type":"array","items":{"type":"array","items":false,"prefixItems":[{"type":"string"},{"type":"integer","format":"int64","minimum":0}]},"description":"`[ip, count]` pairs, highest first."},"top_rules":{"type":"array","items":{"type":"array","items":false,"prefixItems":[{"type":"string"},{"type":"integer","format":"int64","minimum":0}]},"description":"`[rule_name, count]` pairs, highest first."},"rules_count":{"type":"integer","minimum":0}}},"WafStatsResponse":{"type":"object","description":"Combined WAF + DDoS statistics for `GET /v1/waf/stats`.","required":["waf","ddos"],"properties":{"waf":{"$ref":"#/components/schemas/WafStats"},"ddos":{"$ref":"#/components/schemas/DdosStats"}}},"WebhookRequest":{"type":"object","description":"Register a webhook endpoint for a set of event types.","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"secret":{"type":["string","null"]},"active":{"type":["boolean","null"]}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Scalix API key: scalix_sk_... (secret key) or scalix_pat_... (personal access token)"}}},"tags":[{"name":"Account","description":"Account API for Scalix Cloud to inspect the current API key's identity, effective scopes, unlocked MCP tools, plan rate limits, and profile."},{"name":"Database","description":"Database API to run single and batch SQL queries, read query logs, and get anomaly detection, optimization, scaling, and natural-language-to-SQL help."},{"name":"Auth","description":"End-user authentication (signup, login, OAuth, MFA)"},{"name":"AI","description":"Scalix AI inference API: chat completions, streaming, embeddings, image generation, speech, transcription, RAG, and web research through one API."},{"name":"Compute","description":"Compute API to deploy, scale, restart, roll back, and inspect container and VM workloads and Scalix Run services in Scalix Cloud."},{"name":"Sandboxes","description":"Ephemeral microVM sandboxes for agent code execution"},{"name":"Computers","description":"Persistent Linux machines: the root disk and network address survive stop/start, and only DELETE reclaims the disk."},{"name":"Functions","description":"Functions API to deploy, update, invoke, and delete serverless functions in Scalix Cloud, plus read invocation history and runtime logs."},{"name":"Storage","description":"Object storage API for Scalix Cloud with S3-compatible buckets and objects: upload, download, list, delete, read metadata, and presign URLs."},{"name":"Key-Value","description":"Key-value store API for Scalix Cloud with get, set, delete, exists, and list operations plus optional TTL on writes for caching and sessions."},{"name":"Events","description":"Event bus API for Scalix Cloud to create topics, publish events, manage pub/sub subscriptions, and track delivery status across your project."},{"name":"Cron","description":"Cron API to create, update, list, and trigger scheduled jobs in Scalix Cloud and review each schedule's execution history."},{"name":"Metering","description":"Usage metering API to retrieve aggregate and per-API-key usage, budgets, and billing stats for the current period in Scalix Cloud."},{"name":"Billing","description":"Billing API for Scalix Cloud: plans and pricing, hosted checkout and portal, subscriptions, invoices, payment methods, credits and the credit ledger, spending cap, usage analytics and forecast, tax info and calculation, GDPR data-subject ops, and service/module/infra agreements. Tenant identity is resolved server-side from the caller's credential."},{"name":"Vectors","description":"Vector database API for Scalix Cloud to create collections, upsert embeddings in batches, and run nearest-neighbour similarity search per tenant."},{"name":"Realtime","description":"Realtime API to create subscriptions and open WebSocket streams for live, per-tenant database change updates in Scalix Cloud."},{"name":"Webhooks","description":"Webhooks API to register endpoint URLs for tenant event types and list registered webhooks in Scalix Cloud for outbound event delivery."},{"name":"Schema","description":"Schema API to introspect a Scalix Cloud database: list tables, views, and relationships, inspect a table, search columns, and analyze PII."},{"name":"Migrations","description":"Database migrations API to register schema migrations for a tenant and fetch the pending migration plan for a Scalix Cloud database."},{"name":"Encryption","description":"Encryption API to encrypt and decrypt data through Scalix Cloud, returning ciphertext or plaintext for field-level and application-level protection."},{"name":"PITR","description":"Point-in-time recovery API to restore a ScalixNova tenant database to an earlier moment through a single REST endpoint in Scalix Cloud."},{"name":"MCP","description":"Model Context Protocol API to list and call the MCP tools your token unlocks, letting AI agents operate Scalix Cloud through tool calls."},{"name":"Build","description":"Build API to start, monitor, cancel, and read logs for container image builds in Scalix Cloud, with every build scoped to your project."},{"name":"Registry","description":"OCI container registry API for Scalix Cloud implementing the Distribution v2 spec: push and pull image blobs, manifests, tags, and the catalog."},{"name":"Search","description":"Search API for the curated Scalix Search index to run ranked queries, manage source registrations, trigger ingest runs, and read index stats."},{"name":"Compliance","description":"Compliance API to query and export the tenant audit log, manage GDPR data-subject requests, and check compliance status in Scalix Cloud."},{"name":"Domains","description":"Custom domains API to add, verify, and remove domains for a Scalix Cloud project and provision SSL certificates using the required DNS records."},{"name":"VPC","description":"VPC API to list, inspect, and manage private networks and VPC peers for a Scalix Cloud project (VPC provisioning is a planned capability)."},{"name":"Load Balancer","description":"Load balancer API to create and manage layer-7 load balancers in Scalix Cloud and attach or remove backends for distributing traffic."},{"name":"WAF","description":"Web application firewall API for Scalix Cloud to create, update, and delete WAF rules, review recent security events, and read WAF statistics."},{"name":"Shield","description":"AI crawler control — policies, analytics, robots.txt"},{"name":"Integrations","description":"Integrations API to connect GitHub, GitLab, and Bitbucket repos to a Scalix Cloud project, manage the GitHub App, and mint installation tokens."},{"name":"Environment","description":"Environment variables API to list, set, and remove project-level configuration and secrets in Scalix Cloud, with secret values masked on read."},{"name":"Email","description":"Email API to send templated and raw transactional mail from Scalix Cloud, manage templates and org sending settings, register and verify your own sending domains, and read delivery events, suppressions, and analytics."},{"name":"System","description":"System API for Scalix Cloud service status, liveness and readiness probes, and the live OpenAPI specification for diagnostics and monitoring."}]}