{ "openapi": "3.1.0", "info": { "title": "ToolCTRL API", "version": "1.0.0" }, "paths": { "/healthz": { "get": { "operationId": "getHealthz", "security": [], "responses": { "200": { "description": "API liveness status.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "ok" ] }, "service": { "type": "string", "enum": [ "api" ] }, "revision": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "status", "service", "revision", "requestId" ] } } } } } } }, "/v1/health": { "get": { "operationId": "getV1Health", "security": [], "responses": { "200": { "description": "API versioned liveness status.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "ok" ] }, "service": { "type": "string", "enum": [ "api" ] }, "revision": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "status", "service", "revision", "requestId" ] } } } } } } }, "/readyz": { "get": { "operationId": "getReadyz", "security": [], "responses": { "200": { "description": "API readiness status after dependency checks.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "ready" ] }, "service": { "type": "string", "enum": [ "api" ] }, "revision": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "status", "service", "revision", "requestId" ] } } } }, "503": { "description": "API readiness dependency check failed with redacted diagnostics.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "not_ready" ] }, "service": { "type": "string", "enum": [ "api" ] }, "requestId": { "type": "string" }, "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "dependency_unavailable" ] }, "message": { "type": "string" } }, "required": [ "code", "message" ] } }, "required": [ "status", "service", "requestId", "error" ] } } } } } } }, "/status": { "get": { "operationId": "getStatus", "security": [], "responses": { "200": { "description": "API service status payload for uptime monitors.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "ok" ] }, "service": { "type": "string", "enum": [ "api" ] }, "revision": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "status", "service", "revision", "requestId" ] } } } }, "503": { "description": "API readiness dependency check failed with redacted diagnostics.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "not_ready" ] }, "service": { "type": "string", "enum": [ "api" ] }, "requestId": { "type": "string" }, "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "dependency_unavailable" ] }, "message": { "type": "string" } }, "required": [ "code", "message" ] } }, "required": [ "status", "service", "requestId", "error" ] } } } } } } }, "/metrics": { "get": { "operationId": "getMetrics", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Prometheus text-format metrics. Requires the operator METRICS_TOKEN bearer.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "text/plain": { "schema": { "type": "string" } } } }, "401": { "description": "API readiness dependency check failed with redacted diagnostics.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "not_ready" ] }, "service": { "type": "string", "enum": [ "api" ] }, "requestId": { "type": "string" }, "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "dependency_unavailable" ] }, "message": { "type": "string" } }, "required": [ "code", "message" ] } }, "required": [ "status", "service", "requestId", "error" ] } } } }, "404": { "description": "API readiness dependency check failed with redacted diagnostics.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "not_ready" ] }, "service": { "type": "string", "enum": [ "api" ] }, "requestId": { "type": "string" }, "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "dependency_unavailable" ] }, "message": { "type": "string" } }, "required": [ "code", "message" ] } }, "required": [ "status", "service", "requestId", "error" ] } } } } } } }, "/v1/session/current-user": { "get": { "operationId": "getCurrentUserSession", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Authenticated service principal.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "authenticated": { "type": "boolean", "const": true }, "principal": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "service-token" ] } }, "required": [ "type" ] } }, "required": [ "authenticated", "principal" ] } } } }, "401": { "description": "Missing or invalid service-token credentials with a request-ID-correlated JSON error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/docs": { "get": { "operationId": "getApiDocs", "responses": { "200": { "description": "Self-contained API documentation page for the canonical API host.", "content": { "text/html": {} } } } } }, "/v1/openapi.json": { "get": { "operationId": "getOpenApiDocument", "responses": { "200": { "description": "OpenAPI contract for the canonical API host.", "content": { "application/json": {} } } } } }, "/v1/auth/login": { "post": { "operationId": "loginWithPassword", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "properties": { "email": { "type": "string", "minLength": 1 }, "password": { "type": "string", "minLength": 1 } }, "required": [ "email", "password" ] } } } }, "responses": { "200": { "description": "Legacy-compatible JWT login response; also sets an HttpOnly RJ_api_session cookie using the shared session-cookie policy." }, "400": { "description": "Invalid request or credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request", "invalid_credentials" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Unexpected login failure.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_credentials" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "429": { "description": "Login attempt rejected by the fixed-window rate limiter before account lookup or password comparison; response and diagnostics are redacted to avoid credential disclosure.", "headers": { "Retry-After": { "description": "Seconds until the client should retry the login attempt.", "schema": { "type": "integer", "minimum": 1 } }, "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "properties": { "error": { "type": "object", "additionalProperties": false, "properties": { "code": { "type": "string", "enum": [ "rate_limited" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/auth/refresh-token": { "post": { "operationId": "refreshJwtToken", "security": [ { "apiSessionBearer": [] } ], "responses": { "200": { "description": "Legacy-compatible refreshed JWT and user envelope; also sets an HttpOnly RJ_api_session cookie using the shared session-cookie policy." }, "400": { "description": "Decoded token does not map to an active user.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_credentials" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing, invalid or expired token.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "missing_token", "invalid_token" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/auth/logout": { "post": { "operationId": "logoutApiSession", "security": [ { "apiSessionBearer": [] } ], "responses": { "200": { "description": "Revokes the presented active API JWT session and clears the HttpOnly RJ_api_session cookie with an expired shared session-cookie policy." }, "401": { "description": "Missing, invalid, expired, or already-revoked token.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_token" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/api-keys/validate": { "post": { "operationId": "validateApiKey", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] }, {} ], "x-api-key-placeholder": "", "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "properties": { "apiKey": { "type": "string" } } } } } }, "responses": { "200": { "description": "API key validation result.", "content": { "application/json": { "schema": { "type": "object", "properties": { "active": { "type": "boolean" }, "keyType": { "type": "string", "enum": [ "stored-api-key", "service-token" ] }, "apiKey": { "description": "Redacted stored API-key metadata returned only for stored API-key validation results; plaintext key material is never returned by this endpoint.", "type": "object", "properties": { "id": { "type": "string" }, "alias": { "type": "string" }, "tenantId": { "type": "string" }, "tenant": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "slug": { "type": "string" } }, "required": [ "id", "name", "slug" ] }, "expires": { "type": [ "string", "null" ], "format": "date-time" } }, "required": [ "id", "alias", "tenantId", "tenant", "expires" ] } }, "required": [ "active", "keyType" ] } } } }, "400": { "description": "Missing or invalid API key validation input.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request", "api_key_required" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/ai/upload": { "post": { "operationId": "uploadAiFile", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "x-tenant-id", "in": "header", "required": false, "description": "Tenant identifier used to scope the generated storage object key. Preferred over the tenantId query parameter when both are supplied.", "schema": { "type": "string", "minLength": 1 } }, { "name": "tenantId", "in": "query", "required": false, "description": "Fallback tenant identifier used when x-tenant-id is not supplied.", "schema": { "type": "string", "minLength": 1 } }, { "name": "x-filename", "in": "header", "required": false, "description": "Optional source filename used to derive the stored object name. Unsafe path and filename characters are sanitized before persistence.", "schema": { "type": "string", "minLength": 1 } }, { "name": "x-storage-object-status", "in": "header", "required": false, "description": "Optional storage scanner status for upload authorization. Omitted values default to clean; blocked and quarantined values are denied before persistence.", "schema": { "type": "string", "enum": [ "available", "clean", "blocked", "quarantined" ] } } ], "responses": { "200": { "description": "AI file upload response.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "const": true }, "url": { "type": [ "string", "null" ] } }, "required": [ "success", "url" ] } } } }, "400": { "description": "Upload tenant or generated storage object key is invalid.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_tenant", "invalid_key" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing service credentials or S3-compatible upload configuration.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized", "upload_config_missing" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Upload storage access was denied for tenant mismatch, inactive tenant, or blocked/quarantined object status.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "tenant_mismatch", "tenant_inactive", "blocked_object", "quarantined_object" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Upload tenant was not found.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "tenant_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "411": { "description": "Missing or invalid Content-Length header for AI upload.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "content_length_required" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Upload failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "ai_upload_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/support/inbound-email": { "post": { "operationId": "createSupportTicketFromInboundEmail", "description": "Accepts Mailjet inbound (parse) email webhooks authenticated with HTTP Basic Auth and creates an idempotent support ticket for the matched tenant inbound address.", "security": [ { "mailjetWebhookAuth": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "properties": { "messageId": { "type": "string" }, "from": { "oneOf": [ { "type": "string" }, { "type": "object", "properties": { "email": { "type": "string" } } } ] }, "to": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "object", "properties": { "email": { "type": "string" } } } } ] }, "subject": { "type": "string" }, "text": { "type": "string" } } } } } }, "responses": { "201": { "description": "Support ticket created from inbound email." }, "202": { "description": "Inbound email was accepted as duplicate or ignored for an unknown recipient." }, "400": { "description": "Invalid inbound email payload.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing, malformed, or mismatched Mailjet webhook Basic-Auth credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_webhook_signature" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Mailjet webhook authentication is not configured.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "webhook_signing_not_configured" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/analytics/events": { "post": { "operationId": "createAnalyticsEvent", "security": [ { "analyticsTokenHeader": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "properties": { "action": { "type": "string", "minLength": 1 }, "category": { "type": "string", "minLength": 1 }, "label": { "type": "string" }, "value": { "type": "string" }, "url": { "type": "string" }, "route": { "type": "string" }, "analytics": { "type": "object", "additionalProperties": true, "properties": { "userAnalyticsId": { "type": "string", "minLength": 1 }, "portalId": { "type": [ "string", "null" ] }, "portalUserId": { "type": [ "string", "null" ] } }, "required": [ "userAnalyticsId" ] } }, "required": [ "action", "category", "analytics" ] } } } }, "responses": { "201": { "description": "Analytics event recorded.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "const": true } }, "required": [ "success" ] } } } }, "400": { "description": "Invalid analytics event payload.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid analytics token.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Analytics token configuration or event persistence failed.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "analytics_token_not_configured", "analytics_event_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/analytics/page-views": { "post": { "operationId": "createAnalyticsPageView", "security": [ { "analyticsTokenHeader": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "properties": { "url": { "type": "string", "minLength": 1 }, "route": { "type": "string" }, "analytics": { "type": "object", "additionalProperties": true, "properties": { "userAnalyticsId": { "type": "string", "minLength": 1 }, "portalId": { "type": [ "string", "null" ] }, "portalUserId": { "type": [ "string", "null" ] } }, "required": [ "userAnalyticsId" ] } }, "required": [ "url", "analytics" ] } } } }, "responses": { "201": { "description": "Analytics page view recorded.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "const": true } }, "required": [ "success" ] } } } }, "204": { "description": "Page view ignored by analytics settings." }, "400": { "description": "Invalid analytics page-view payload.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid analytics token.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Analytics token configuration or page-view persistence failed.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "analytics_token_not_configured", "analytics_page_view_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/analytics/public": { "get": { "operationId": "getPublicAnalyticsOverview", "security": [ { "analyticsTokenHeader": [] } ], "parameters": [ { "name": "period", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "last-7-days", "last-30-days", "last-90-days" ] } } ], "responses": { "200": { "description": "Public analytics overview.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "uniqueVisitors": { "type": "number" }, "pageViews": { "type": "number" }, "events": { "type": "number" }, "liveVisitors": { "type": "number" }, "top": { "type": "object", "additionalProperties": true }, "charts": { "type": "object", "additionalProperties": true } }, "required": [ "uniqueVisitors", "pageViews", "events", "liveVisitors", "top", "charts" ] } } } }, "400": { "description": "Invalid period.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_period" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid analytics token.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Public analytics overview is disabled.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Analytics token configuration or read failed.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "analytics_token_not_configured", "analytics_overview_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/workspaces/{tenantId}/context/revalidate": { "post": { "operationId": "revalidateWorkspaceContext", "description": "Revalidates a workspace context switch for a tenant/user pair using service-token credentials. The response is a request-ID-correlated, redacted context validity envelope and never includes SSO provider secrets or invite/token material.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "tenantId", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "properties": { "userId": { "type": "string", "minLength": 1 }, "providerSlug": { "type": "string", "minLength": 1, "description": "Optional non-authoritative provider slug echo; tenant/user membership remains the only context revalidation authority." } }, "required": [ "userId" ] } } } }, "responses": { "200": { "description": "Workspace context remains valid for the tenant/user membership.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "context": { "type": "object", "description": "Redacted workspace context validity envelope. It confirms tenant/user membership and may echo a requested providerSlug, but never includes provider secrets, invite tokens, token hashes, SAML certificates, or OIDC client secrets.", "properties": { "valid": { "type": "boolean", "const": true }, "tenantId": { "type": "string" }, "userId": { "type": "string" }, "providerSlug": { "type": "string" } }, "required": [ "valid", "tenantId", "userId" ] } }, "required": [ "context" ] } } } }, "400": { "description": "Invalid context revalidation route or payload; requestId correlates the redacted validation error.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request", "context_missing_tenant_id", "context_missing_user_id" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service-token credential.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Tenant/user context is not an active membership for this workspace.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "context_membership_not_found", "context_membership_not_active" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Workspace context revalidation failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "workspace_context_revalidation_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/workspaces/{tenantId}/auth/providers": { "get": { "operationId": "listWorkspaceAuthProviders", "description": "Lists redacted tenant-scoped OIDC/SAML provider metadata for service-token callers. Responses expose provider status and non-secret endpoints only; client secrets, SAML certificates/private keys, token hashes, invite tokens, and raw metadata documents are omitted.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "tenantId", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } }, { "name": "kind", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "oidc", "saml" ] } }, { "name": "enabled", "in": "query", "required": false, "schema": { "type": "boolean" } } ], "responses": { "200": { "description": "Redacted workspace SSO provider metadata list.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "providers": { "type": "array", "items": { "type": "object", "description": "Redacted tenant-scoped OIDC/SAML provider metadata. Client secrets, SAML private keys, full certificates, token hashes, invite tokens, and raw metadata documents are intentionally omitted; certificateFingerprint is a non-secret audit fingerprint only.", "properties": { "id": { "type": "string" }, "tenantId": { "type": "string" }, "kind": { "type": "string", "enum": [ "oidc", "saml" ] }, "name": { "type": "string" }, "slug": { "type": "string" }, "enabled": { "type": "boolean" }, "status": { "type": "string", "enum": [ "enabled", "disabled" ] }, "issuer": { "type": [ "string", "null" ] }, "authorizationUrl": { "type": [ "string", "null" ], "format": "uri" }, "tokenUrl": { "type": [ "string", "null" ], "format": "uri" }, "jwksUrl": { "type": [ "string", "null" ], "format": "uri" }, "clientId": { "type": [ "string", "null" ], "description": "OIDC public client identifier when configured; client secrets are never stored or returned by this schema stub." }, "entityId": { "type": [ "string", "null" ] }, "ssoUrl": { "type": [ "string", "null" ], "format": "uri" }, "certificateFingerprint": { "type": [ "string", "null" ], "description": "Non-secret SAML certificate fingerprint for audit correlation; full certificate material is never returned." }, "metadataUpdatedAt": { "type": [ "string", "null" ], "format": "date-time" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } }, "required": [ "id", "tenantId", "kind", "name", "slug", "enabled", "status", "issuer", "authorizationUrl", "tokenUrl", "jwksUrl", "clientId", "entityId", "ssoUrl", "certificateFingerprint", "metadataUpdatedAt", "createdAt", "updatedAt" ] } } }, "required": [ "providers" ] } } } }, "400": { "description": "Invalid workspace auth provider route or filter parameters.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service-token credential.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Caller is not allowed to inspect workspace provider metadata for this tenant.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "tenant_inactive", "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Workspace tenant was not found for provider discovery.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "tenant_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Workspace auth provider listing failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "workspace_auth_provider_failed", "workspace_tenant_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/workspaces/{tenantId}/invites": { "get": { "operationId": "listWorkspaceInvites", "description": "Lists tenant-scoped workspace invites for service-token callers. Response envelopes expose lifecycle timestamps, status, and tokenPrefix only while omitting reusable invite token material.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "tenantId", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } }, { "name": "status", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "pending", "accepted", "revoked", "expired" ] } }, { "name": "email", "in": "query", "required": false, "schema": { "type": "string", "minLength": 1, "format": "email" } } ], "responses": { "200": { "description": "Tenant workspace invite list with redacted token metadata.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "invites": { "type": "array", "items": { "type": "object", "description": "Redacted workspace invite lifecycle envelope. It includes tokenPrefix for audit correlation while omitting secret invite material; the create response returns the one-time invite token separately.", "properties": { "id": { "type": "string" }, "tenantId": { "type": "string" }, "email": { "type": "string", "format": "email" }, "firstName": { "type": "string" }, "lastName": { "type": "string" }, "type": { "type": "integer" }, "status": { "type": "string", "enum": [ "pending", "accepted", "revoked", "expired" ] }, "pending": { "type": "boolean" }, "tokenPrefix": { "type": [ "string", "null" ], "description": "Short non-secret token prefix for audit correlation only; full invite token material is never included in invite envelopes." }, "createdUserId": { "type": [ "string", "null" ] }, "fromUserId": { "type": [ "string", "null" ] }, "acceptedByUserId": { "type": [ "string", "null" ] }, "revokedByUserId": { "type": [ "string", "null" ] }, "createdAt": { "type": [ "string", "null" ], "format": "date-time" }, "expiresAt": { "type": [ "string", "null" ], "format": "date-time" }, "acceptedAt": { "type": [ "string", "null" ], "format": "date-time" }, "revokedAt": { "type": [ "string", "null" ], "format": "date-time" } }, "required": [ "id", "tenantId", "email", "firstName", "lastName", "type", "status", "pending", "tokenPrefix", "createdUserId", "fromUserId", "acceptedByUserId", "revokedByUserId", "createdAt", "expiresAt", "acceptedAt", "revokedAt" ] } } }, "required": [ "invites" ] } } } }, "400": { "description": "Invalid workspace invite list route parameters.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service-token credential.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Workspace tenant is inactive for invite listing.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "tenant_inactive" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Workspace tenant was not found for invite listing.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "tenant_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Workspace invite list failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "workspace_invite_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } }, "post": { "operationId": "createWorkspaceInvite", "description": "Creates a tenant workspace invite. The response includes the one-time invite token only in the top-level token field; invite envelopes expose only tokenPrefix and never reusable token examples.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "tenantId", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "properties": { "email": { "type": "string", "minLength": 1, "format": "email" }, "firstName": { "type": "string", "minLength": 1 }, "lastName": { "type": "string", "minLength": 1 }, "type": { "type": "integer" }, "expiresAt": { "type": "string", "format": "date-time" } }, "required": [ "email", "firstName", "lastName", "type" ] } } } }, "responses": { "201": { "description": "Workspace invite created; persist the one-time token outside the API because it cannot be recovered later.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "invite": { "type": "object", "description": "Redacted workspace invite lifecycle envelope. It includes tokenPrefix for audit correlation while omitting secret invite material; the create response returns the one-time invite token separately.", "properties": { "id": { "type": "string" }, "tenantId": { "type": "string" }, "email": { "type": "string", "format": "email" }, "firstName": { "type": "string" }, "lastName": { "type": "string" }, "type": { "type": "integer" }, "status": { "type": "string", "enum": [ "pending", "accepted", "revoked", "expired" ] }, "pending": { "type": "boolean" }, "tokenPrefix": { "type": [ "string", "null" ], "description": "Short non-secret token prefix for audit correlation only; full invite token material is never included in invite envelopes." }, "createdUserId": { "type": [ "string", "null" ] }, "fromUserId": { "type": [ "string", "null" ] }, "acceptedByUserId": { "type": [ "string", "null" ] }, "revokedByUserId": { "type": [ "string", "null" ] }, "createdAt": { "type": [ "string", "null" ], "format": "date-time" }, "expiresAt": { "type": [ "string", "null" ], "format": "date-time" }, "acceptedAt": { "type": [ "string", "null" ], "format": "date-time" }, "revokedAt": { "type": [ "string", "null" ], "format": "date-time" } }, "required": [ "id", "tenantId", "email", "firstName", "lastName", "type", "status", "pending", "tokenPrefix", "createdUserId", "fromUserId", "acceptedByUserId", "revokedByUserId", "createdAt", "expiresAt", "acceptedAt", "revokedAt" ] }, "token": { "type": "string", "description": "One-time invite token returned only at creation. No example value is documented to avoid secret leakage." } }, "required": [ "invite", "token" ] } } } }, "400": { "description": "Invalid workspace invite create payload or tenant route parameter.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request", "invite_already_finalized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service-token credential.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Workspace tenant is inactive for invite creation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "tenant_inactive" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Workspace tenant was not found for invite creation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "tenant_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "409": { "description": "A pending non-expired invite already exists for the tenant and email.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "duplicate_active_invite" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Workspace invite creation failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "workspace_invite_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/workspaces/{tenantId}/invites/{inviteId}/accept": { "post": { "operationId": "acceptWorkspaceInvite", "description": "Accepts a workspace invite with a one-time token in the request body. Success and error responses are redacted and never echo the token.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "tenantId", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } }, { "name": "inviteId", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "properties": { "token": { "type": "string", "minLength": 1, "description": "One-time invite token supplied by the invitee; never echoed in success or error responses." }, "userId": { "type": "string", "minLength": 1 } }, "required": [ "token" ] } } } }, "responses": { "200": { "description": "Workspace invite accepted with redacted token metadata.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "invite": { "type": "object", "description": "Redacted workspace invite lifecycle envelope. It includes tokenPrefix for audit correlation while omitting secret invite material; the create response returns the one-time invite token separately.", "properties": { "id": { "type": "string" }, "tenantId": { "type": "string" }, "email": { "type": "string", "format": "email" }, "firstName": { "type": "string" }, "lastName": { "type": "string" }, "type": { "type": "integer" }, "status": { "type": "string", "enum": [ "pending", "accepted", "revoked", "expired" ] }, "pending": { "type": "boolean" }, "tokenPrefix": { "type": [ "string", "null" ], "description": "Short non-secret token prefix for audit correlation only; full invite token material is never included in invite envelopes." }, "createdUserId": { "type": [ "string", "null" ] }, "fromUserId": { "type": [ "string", "null" ] }, "acceptedByUserId": { "type": [ "string", "null" ] }, "revokedByUserId": { "type": [ "string", "null" ] }, "createdAt": { "type": [ "string", "null" ], "format": "date-time" }, "expiresAt": { "type": [ "string", "null" ], "format": "date-time" }, "acceptedAt": { "type": [ "string", "null" ], "format": "date-time" }, "revokedAt": { "type": [ "string", "null" ], "format": "date-time" } }, "required": [ "id", "tenantId", "email", "firstName", "lastName", "type", "status", "pending", "tokenPrefix", "createdUserId", "fromUserId", "acceptedByUserId", "revokedByUserId", "createdAt", "expiresAt", "acceptedAt", "revokedAt" ] } }, "required": [ "invite" ] } } } }, "400": { "description": "Invalid workspace invite accept payload or finalized invite state.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request", "invite_already_finalized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service-token credential.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Workspace tenant is inactive for invite acceptance.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "tenant_inactive" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Workspace invite or tenant was not found for the tenant/token scope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invite_not_found", "tenant_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "410": { "description": "Workspace invite token is expired and cannot be accepted.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invite_expired" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Workspace invite acceptance failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "workspace_invite_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/workspaces/{tenantId}/invites/{inviteId}/revoke": { "post": { "operationId": "revokeWorkspaceInvite", "description": "Revokes a pending workspace invite by tenant and invite id. Request and error paths do not expose token material.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "tenantId", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } }, { "name": "inviteId", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "properties": { "reason": { "type": "string" }, "revokedByUserId": { "type": "string", "minLength": 1 } } } } } }, "responses": { "200": { "description": "Workspace invite revoked with redacted token metadata.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "invite": { "type": "object", "description": "Redacted workspace invite lifecycle envelope. It includes tokenPrefix for audit correlation while omitting secret invite material; the create response returns the one-time invite token separately.", "properties": { "id": { "type": "string" }, "tenantId": { "type": "string" }, "email": { "type": "string", "format": "email" }, "firstName": { "type": "string" }, "lastName": { "type": "string" }, "type": { "type": "integer" }, "status": { "type": "string", "enum": [ "pending", "accepted", "revoked", "expired" ] }, "pending": { "type": "boolean" }, "tokenPrefix": { "type": [ "string", "null" ], "description": "Short non-secret token prefix for audit correlation only; full invite token material is never included in invite envelopes." }, "createdUserId": { "type": [ "string", "null" ] }, "fromUserId": { "type": [ "string", "null" ] }, "acceptedByUserId": { "type": [ "string", "null" ] }, "revokedByUserId": { "type": [ "string", "null" ] }, "createdAt": { "type": [ "string", "null" ], "format": "date-time" }, "expiresAt": { "type": [ "string", "null" ], "format": "date-time" }, "acceptedAt": { "type": [ "string", "null" ], "format": "date-time" }, "revokedAt": { "type": [ "string", "null" ], "format": "date-time" } }, "required": [ "id", "tenantId", "email", "firstName", "lastName", "type", "status", "pending", "tokenPrefix", "createdUserId", "fromUserId", "acceptedByUserId", "revokedByUserId", "createdAt", "expiresAt", "acceptedAt", "revokedAt" ] } }, "required": [ "invite" ] } } } }, "400": { "description": "Invalid workspace invite revoke payload, route parameter, or finalized invite state.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request", "invite_already_finalized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service-token credential.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Workspace tenant is inactive for invite revocation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "tenant_inactive" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Workspace invite or tenant was not found for the tenant scope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invite_not_found", "tenant_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Workspace invite revocation failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "workspace_invite_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/analytics/admin": { "get": { "operationId": "getAdminAnalyticsOverview", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "period", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "last-7-days", "last-30-days", "last-90-days" ] } }, { "name": "portalId", "in": "query", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Admin analytics overview.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "uniqueVisitors": { "type": "number" }, "pageViews": { "type": "number" }, "events": { "type": "number" }, "liveVisitors": { "type": "number" }, "top": { "type": "object", "additionalProperties": true }, "charts": { "type": "object", "additionalProperties": true } }, "required": [ "uniqueVisitors", "pageViews", "events", "liveVisitors", "top", "charts" ] } } } }, "400": { "description": "Invalid period.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_period" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Analytics overview read failed.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "analytics_overview_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/notifications/stream": { "get": { "operationId": "streamNotifications", "description": "Streams bounded, tenant/user scoped notification delivery diagnostics as sanitized SSE frames for authenticated service clients. The initial snapshot and reconnect cursor are deterministic for Last-Event-ID resume semantics; the stream does not expose provider payloads, provider message ids, metadata, tokens, request bodies, or raw secrets.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "x-toolctrl-tenant-id", "in": "header", "required": false, "description": "Preferred tenant scope for internal web-to-API notification streams. Used before the legacy tenantId query parameter.", "schema": { "type": "string", "minLength": 1 } }, { "name": "x-toolctrl-user-id", "in": "header", "required": false, "description": "Preferred user scope for internal web-to-API notification streams. Used before the legacy userId query parameter.", "schema": { "type": "string", "minLength": 1 } }, { "name": "tenantId", "in": "query", "required": false, "deprecated": true, "description": "Legacy tenant scope fallback. Prefer x-toolctrl-tenant-id so identifiers are not logged in URLs.", "schema": { "type": "string", "minLength": 1 } }, { "name": "userId", "in": "query", "required": false, "deprecated": true, "description": "Legacy user scope fallback. Prefer x-toolctrl-user-id so identifiers are not logged in URLs.", "schema": { "type": "string", "minLength": 1 } }, { "name": "Last-Event-ID", "in": "header", "required": false, "description": "Optional redacted stream cursor used to resume after the last delivered SSE event.", "schema": { "type": "string", "minLength": 1 } } ], "responses": { "200": { "description": "Server-Sent Events stream that emits one bounded sanitized snapshot, notification update events for delivery snapshots, keepalive comments, and sanitized error events when diagnostics lookup fails. Reconnect with Last-Event-ID to resume after the last redacted cursor; provider payloads, provider message ids, metadata, request bodies, and raw secrets are never serialized.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } }, "cache-control": { "description": "No-cache directive for the live stream response.", "schema": { "type": "string", "enum": [ "no-cache" ] } } }, "content": { "text/event-stream": { "schema": { "type": "string", "description": "SSE frames use event types snapshot, notification, and error with redacted id/cursor values, plus keepalive comments. Data payloads contain requestId, cursor, and sanitized delivery items only." } } } }, "400": { "description": "Missing tenantId or userId notification stream scope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Notification stream diagnostics lookup failed with a sanitized SSE error event before close.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "notification_stream_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/accounts": { "get": { "operationId": "listAccounts", "description": "Lists tenant account metadata and subscription summaries for service-token callers from the canonical API runtime.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Account list response.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "const": true }, "total_results": { "type": "number" }, "data": { "type": "array", "items": { "type": "object", "additionalProperties": true, "properties": { "id": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }, "slug": { "type": "string" }, "name": { "type": "string" }, "icon": { "type": [ "string", "null" ] }, "subscription": { "anyOf": [ { "type": "object", "additionalProperties": true, "properties": { "id": { "type": "string" }, "stripeCustomerId": { "type": [ "string", "null" ] }, "products": { "type": "array", "items": { "type": "object", "additionalProperties": true } } }, "required": [ "id", "products" ] }, { "type": "null" } ] } }, "required": [ "id", "createdAt", "updatedAt", "slug", "name", "icon", "subscription" ] } } }, "required": [ "success", "total_results", "data" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/accounts/{id}": { "get": { "operationId": "getAccount", "description": "Looks up one tenant account by id or slug for service-token callers from the canonical API runtime.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } } ], "responses": { "200": { "description": "Single account response.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "additionalProperties": true, "properties": { "id": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" }, "slug": { "type": "string" }, "name": { "type": "string" }, "icon": { "type": [ "string", "null" ] }, "subscription": { "anyOf": [ { "type": "object", "additionalProperties": true, "properties": { "id": { "type": "string" }, "stripeCustomerId": { "type": [ "string", "null" ] }, "products": { "type": "array", "items": { "type": "object", "additionalProperties": true } } }, "required": [ "id", "products" ] }, { "type": "null" } ] } }, "required": [ "id", "createdAt", "updatedAt", "slug", "name", "icon", "subscription" ] } }, "required": [ "success", "data" ] } } } }, "400": { "description": "Invalid account route parameter.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Account was not found.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "account_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/usage": { "get": { "operationId": "getApiUsage", "description": "Canonical API-host entry point for API usage metadata. The API runtime validates the tenant API key and reads usage state through DB package boundaries.", "security": [ { "apiKeyHeader": [] } ], "responses": { "200": { "description": "Plan and remaining usage metadata for the credential-scoped tenant.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "plan": { "type": "string" }, "remaining": { "type": [ "number", "null" ] } }, "required": [ "plan" ] } } } }, "400": { "description": "Invalid usage request.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid API key credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "402": { "description": "API usage is disabled or exhausted for the credential-scoped tenant.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "payment_required" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "API key credentials are valid but not permitted for this usage lookup.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "429": { "description": "Usage lookup was rate limited.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "rate_limited" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/billing/stripe/webhooks": { "post": { "operationId": "receiveStripeBillingWebhook", "description": "Canonical API-host entry point for Stripe billing lifecycle webhooks. The API runtime preserves the raw body and signature headers and applies subscription updates through API-owned billing services.", "security": [ { "stripeWebhookSignature": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "responses": { "200": { "description": "Webhook accepted by the billing webhook boundary.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } } }, "400": { "description": "Missing or invalid Stripe webhook signature.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_signature" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/email-sequences/mailjet/webhooks": { "post": { "operationId": "receiveEmailSequenceMailjetWebhook", "description": "Accepts Mailjet provider event webhooks for email sequences, authenticated with HTTP Basic Auth. Bounce, blocked, and spam events correlate by provider message id (Message_GUID), mark the sequence delivery bounced, and fail the in-flight run without echoing provider payloads.", "security": [ { "mailjetWebhookAuth": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "responses": { "202": { "description": "Provider webhook accepted. Non-bounce events and unknown provider message ids are ignored to avoid retry storms.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } } }, "400": { "description": "Invalid Mailjet sequence webhook payload.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing, malformed, or mismatched Mailjet webhook Basic-Auth credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_webhook_signature" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Mailjet webhook authentication is unavailable or sequence webhook processing failed.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "webhook_signing_not_configured", "email_sequence_webhook_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/events/webhooks/attempts/{id}": { "post": { "operationId": "retryEventWebhookAttempt", "security": [ { "mailjetWebhookAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Legacy-compatible event webhook delivery attempt response." }, "400": { "description": "Invalid attempt or delivery failure." }, "401": { "description": "Missing, malformed, or mismatched Mailjet webhook Basic-Auth credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_webhook_signature" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Mailjet webhook authentication is not configured.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "webhook_signing_not_configured" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "503": { "description": "Webhook delivery queue is unavailable.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "maintenance_queue_unavailable" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/maintenance/export-retention/enqueue": { "post": { "operationId": "enqueueExportArtifactRetention", "description": "Queues the expired export artifact retention cleanup job for operators. Optional Idempotency-Key deduplicates operator retries; x-request-id remains correlation-only. The response does not expose Redis or storage credentials.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "Idempotency-Key", "in": "header", "required": false, "description": "Optional retry dedupe key. Reusing the same key for this operator enqueue request maps to the same queue job; x-request-id remains correlation-only.", "schema": { "type": "string", "minLength": 1 } } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "properties": { "take": { "type": "integer", "minimum": 1, "maximum": 500 } } } } } }, "responses": { "202": { "description": "Export artifact retention cleanup was enqueued.", "content": { "application/json": { "schema": { "type": "object", "required": [ "enqueued", "task", "jobId", "requestId" ], "properties": { "enqueued": { "type": "boolean", "enum": [ true ] }, "task": { "type": "string", "enum": [ "expired-export-artifacts" ] }, "jobId": { "type": "string" }, "requestId": { "type": "string" } } } } } }, "400": { "description": "Invalid export retention enqueue payload.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "503": { "description": "Maintenance queue Redis connection is not configured.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "maintenance_queue_unavailable" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/entities/{entity}/rows": { "get": { "operationId": "listLegacyEntityRows", "description": "Authorize with either the configured service token bearer credential or a stored API key supplied in x-api-key. Stored API keys are tenant-bound and must include an entity permission for the resolved tenant/entity plus the documented CRUD operation.", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] } ], "x-api-key-permissions": { "credential": "apiKeyHeader", "tenant": { "source": "query", "name": "tenantId", "required": true }, "entity": { "source": "path", "name": "entity" }, "operation": "read" }, "parameters": [ { "name": "entity", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "tenantId", "in": "query", "required": true, "schema": { "type": "string" } }, { "name": "page", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "default": 1 } }, { "name": "pageSize", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } } ], "responses": { "200": { "description": "Legacy-compatible paginated entity row collection.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "const": true }, "page": { "type": "integer" }, "total_pages": { "type": "integer" }, "total_results": { "type": "integer" }, "results": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "data": { "type": "array", "items": { "type": "object", "additionalProperties": true } } }, "required": [ "success", "page", "total_pages", "total_results", "results", "data" ] } } } }, "400": { "description": "Invalid pagination parameters.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_pagination" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Stored API key is inactive, tenant-mismatched, or lacks the required entity CRUD scope for this operation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } }, "post": { "operationId": "createLegacyEntityRow", "description": "Authorize with either the configured service token bearer credential or a stored API key supplied in x-api-key. Stored API keys are tenant-bound and must include an entity permission for the resolved tenant/entity plus the documented CRUD operation.", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] } ], "x-api-key-permissions": { "credential": "apiKeyHeader", "tenant": { "source": "query", "name": "tenantId", "required": true }, "entity": { "source": "path", "name": "entity" }, "operation": "create" }, "x-idempotency-key": "required", "parameters": [ { "name": "Idempotency-Key", "in": "header", "required": true, "description": "Required for protected mutating entity-row and relationship operations. Reusing the same key with the same request fingerprint replays the first successful response; reusing it with a different fingerprint returns a request-ID-correlated conflict. Fingerprints are redacted and never store raw credentials or plaintext request bodies.", "schema": { "type": "string", "minLength": 1 } }, { "name": "entity", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "tenantId", "in": "query", "required": true, "schema": { "type": "string" } } ], "responses": { "201": { "description": "Legacy-compatible created entity row envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "Invalid JSON row payload. Idempotency-Key header is required for idempotent mutations.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_json", "idempotency_key_required" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Stored API key is inactive, tenant-mismatched, or lacks the required entity CRUD scope for this operation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "409": { "description": "Idempotency-Key was already used with a different redacted request fingerprint; inspect x-request-id to correlate the conflict without exposing credentials or request body secrets.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "idempotency_key_conflict" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } }, "/v1/entities/{entity}/rows/{rowId}": { "get": { "operationId": "getLegacyEntityRow", "description": "Authorize with either the configured service token bearer credential or a stored API key supplied in x-api-key. Stored API keys are tenant-bound and must include an entity permission for the resolved tenant/entity plus the documented CRUD operation.", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] } ], "x-api-key-permissions": { "credential": "apiKeyHeader", "tenant": { "source": "query", "name": "tenantId", "required": true }, "entity": { "source": "path", "name": "entity" }, "operation": "read" }, "parameters": [ { "name": "entity", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "rowId", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "tenantId", "in": "query", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Legacy-compatible entity row object.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "Invalid row item route parameters.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Stored API key is inactive, tenant-mismatched, or lacks the required entity CRUD scope for this operation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Entity or row was not found for the scoped tenant.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "entity_not_found", "row_not_found" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } }, "patch": { "operationId": "updateLegacyEntityRow", "description": "Authorize with either the configured service token bearer credential or a stored API key supplied in x-api-key. Stored API keys are tenant-bound and must include an entity permission for the resolved tenant/entity plus the documented CRUD operation.", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] } ], "x-api-key-permissions": { "credential": "apiKeyHeader", "tenant": { "source": "query", "name": "tenantId", "required": true }, "entity": { "source": "path", "name": "entity" }, "operation": "update" }, "x-idempotency-key": "required", "parameters": [ { "name": "Idempotency-Key", "in": "header", "required": true, "description": "Required for protected mutating entity-row and relationship operations. Reusing the same key with the same request fingerprint replays the first successful response; reusing it with a different fingerprint returns a request-ID-correlated conflict. Fingerprints are redacted and never store raw credentials or plaintext request bodies.", "schema": { "type": "string", "minLength": 1 } }, { "name": "entity", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "rowId", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "tenantId", "in": "query", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Legacy-compatible updated entity row object.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "Invalid JSON row payload or row item route parameters. Idempotency-Key header is required for idempotent mutations.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_json", "invalid_request", "idempotency_key_required" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Stored API key is inactive, tenant-mismatched, or lacks the required entity CRUD scope for this operation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Entity or row was not found for the scoped tenant.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "entity_not_found", "row_not_found" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "409": { "description": "Idempotency-Key was already used with a different redacted request fingerprint; inspect x-request-id to correlate the conflict without exposing credentials or request body secrets.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "idempotency_key_conflict" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } }, "delete": { "operationId": "deleteLegacyEntityRow", "description": "Authorize with either the configured service token bearer credential or a stored API key supplied in x-api-key. Stored API keys are tenant-bound and must include an entity permission for the resolved tenant/entity plus the documented CRUD operation.", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] } ], "x-api-key-permissions": { "credential": "apiKeyHeader", "tenant": { "source": "query", "name": "tenantId", "required": true }, "entity": { "source": "path", "name": "entity" }, "operation": "delete" }, "x-idempotency-key": "required", "parameters": [ { "name": "Idempotency-Key", "in": "header", "required": true, "description": "Required for protected mutating entity-row and relationship operations. Reusing the same key with the same request fingerprint replays the first successful response; reusing it with a different fingerprint returns a request-ID-correlated conflict. Fingerprints are redacted and never store raw credentials or plaintext request bodies.", "schema": { "type": "string", "minLength": 1 } }, { "name": "entity", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "rowId", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "tenantId", "in": "query", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Legacy-compatible entity row deletion confirmation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "const": true }, "id": { "type": "string" } }, "required": [ "success", "id" ] } } } }, "400": { "description": "Invalid row item route parameters. Idempotency-Key header is required for idempotent mutations.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request", "idempotency_key_required" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Stored API key is inactive, tenant-mismatched, or lacks the required entity CRUD scope for this operation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Entity or row was not found for the scoped tenant.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "entity_not_found", "row_not_found" ] }, "message": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "409": { "description": "Idempotency-Key was already used with a different redacted request fingerprint; inspect x-request-id to correlate the conflict without exposing credentials or request body secrets.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "idempotency_key_conflict" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/relationships": { "post": { "operationId": "createLegacyRowRelationship", "description": "Authorize with either the configured service token bearer credential or a stored API key supplied in x-api-key. Stored API keys are tenant-bound and must include an entity permission for the resolved tenant/entity plus the documented CRUD operation.", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] } ], "x-api-key-permissions": { "credential": "apiKeyHeader", "tenant": { "source": "query", "name": "tenantId", "required": false }, "relationship": { "idSource": "requestBody.parent/requestBody.child", "parentEntity": "resolved from parent row", "childEntity": "resolved from child row" }, "entityPermissions": [ { "entity": { "source": "relationship.parentEntity" }, "operation": "create" }, { "entity": { "source": "relationship.childEntity" }, "operation": "create" } ] }, "x-idempotency-key": "required", "parameters": [ { "name": "Idempotency-Key", "in": "header", "required": true, "description": "Required for protected mutating entity-row and relationship operations. Reusing the same key with the same request fingerprint replays the first successful response; reusing it with a different fingerprint returns a request-ID-correlated conflict. Fingerprints are redacted and never store raw credentials or plaintext request bodies.", "schema": { "type": "string", "minLength": 1 } }, { "name": "tenantId", "in": "query", "required": true, "schema": { "type": "string", "minLength": 1 } } ], "responses": { "201": { "description": "Legacy-compatible created row relationship envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "relationship": { "type": "object", "additionalProperties": true } }, "required": [ "relationship" ] } } } }, "400": { "description": "Invalid JSON relationship payload, relationship ids, or missing tenantId. Idempotency-Key header is required for idempotent mutations.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request", "idempotency_key_required" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Stored API key is inactive, tenant-mismatched, or lacks the required entity CRUD scope for this operation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Parent row, child row, row tenant scope, or entity relationship was not found.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "parent_row_not_found", "child_row_not_found", "relationship_rows_not_found", "entity_relationship_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "409": { "description": "Idempotency-Key was already used with a different redacted request fingerprint; inspect x-request-id to correlate the conflict without exposing credentials or request body secrets.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "idempotency_key_conflict" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "413": { "description": "JSON request body exceeded the configured limit and was rejected before validation or persistence work ran.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "body_too_large" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Relationship persistence failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "relationship_create_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "properties": { "parent": { "type": "string", "minLength": 1 }, "child": { "type": "string", "minLength": 1 } }, "required": [ "parent", "child" ] } } } } } }, "/v1/relationships/{id}": { "get": { "operationId": "getLegacyRowRelationship", "description": "Authorize with either the configured service token bearer credential or a stored API key supplied in x-api-key. Stored API keys are tenant-bound and must include an entity permission for the resolved tenant/entity plus the documented CRUD operation.", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] } ], "x-api-key-permissions": { "credential": "apiKeyHeader", "tenant": { "source": "query", "name": "tenantId", "required": false }, "relationship": { "idSource": "path.id", "parentEntity": "resolved from parent row", "childEntity": "resolved from child row" }, "entityPermissions": [ { "entity": { "source": "relationship.parentEntity" }, "operation": "read" }, { "entity": { "source": "relationship.childEntity" }, "operation": "read" } ] }, "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "tenantId", "in": "query", "required": true, "schema": { "type": "string", "minLength": 1 } } ], "responses": { "200": { "description": "Legacy-compatible row relationship envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "relationship": { "type": "object", "additionalProperties": true } }, "required": [ "relationship" ] } } } }, "400": { "description": "Invalid relationship route parameters.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Stored API key is inactive, tenant-mismatched, or lacks the required entity CRUD scope for this operation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Relationship, parent row, or child row was not found.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "relationship_not_found", "parent_row_not_found", "child_row_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Relationship lookup failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "relationship_get_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } }, "delete": { "operationId": "deleteLegacyRowRelationship", "description": "Authorize with either the configured service token bearer credential or a stored API key supplied in x-api-key. Stored API keys are tenant-bound and must include an entity permission for the resolved tenant/entity plus the documented CRUD operation.", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] } ], "x-api-key-permissions": { "credential": "apiKeyHeader", "tenant": { "source": "query", "name": "tenantId", "required": false }, "relationship": { "idSource": "path.id", "parentEntity": "resolved from parent row", "childEntity": "resolved from child row" }, "entityPermissions": [ { "entity": { "source": "relationship.parentEntity" }, "operation": "delete" }, { "entity": { "source": "relationship.childEntity" }, "operation": "delete" } ] }, "x-idempotency-key": "required", "parameters": [ { "name": "Idempotency-Key", "in": "header", "required": true, "description": "Required for protected mutating entity-row and relationship operations. Reusing the same key with the same request fingerprint replays the first successful response; reusing it with a different fingerprint returns a request-ID-correlated conflict. Fingerprints are redacted and never store raw credentials or plaintext request bodies.", "schema": { "type": "string", "minLength": 1 } }, { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "tenantId", "in": "query", "required": true, "schema": { "type": "string", "minLength": 1 } } ], "responses": { "200": { "description": "Legacy-compatible row relationship deletion envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "deleted": { "type": "object", "additionalProperties": true } }, "required": [ "deleted" ] } } } }, "400": { "description": "Invalid relationship route parameters. Idempotency-Key header is required for idempotent mutations.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request", "idempotency_key_required" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Stored API key is inactive, tenant-mismatched, or lacks the required entity CRUD scope for this operation.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Relationship, parent row, or child row was not found.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "relationship_not_found", "parent_row_not_found", "child_row_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "409": { "description": "Idempotency-Key was already used with a different redacted request fingerprint; inspect x-request-id to correlate the conflict without exposing credentials or request body secrets.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "idempotency_key_conflict" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Relationship deletion failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "relationship_delete_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/exports/{exportJobId}/download-url": { "get": { "operationId": "getExportDownloadUrl", "description": "Creates a short-lived signed GET URL for a completed, unexpired export job. Authorize with either the configured service token bearer credential or a tenant-bound stored API key supplied in x-api-key; stored API keys are scoped to their own tenant and this route does not publish CRUD entity-scope claims. Responses never include export artifact bucket/key values, storage credentials, signed URL internals beyond the URL envelope, payload filters, or object bodies.", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] } ], "x-api-key-placeholder": "", "parameters": [ { "name": "exportJobId", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } }, { "name": "tenantId", "in": "query", "required": false, "description": "Optional tenant lookup scope for service credentials. Stored API keys always use the key tenant instead of this value.", "schema": { "type": "string", "minLength": 1 } } ], "responses": { "200": { "description": "Short-lived signed download URL envelope for a completed export artifact.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "exportJobId": { "type": "string" }, "requestId": { "type": "string" }, "method": { "type": "string", "enum": [ "GET" ] }, "url": { "type": "string", "format": "uri" }, "expiresAt": { "type": "string", "format": "date-time" }, "expiresInSeconds": { "type": "integer", "enum": [ 300 ] }, "headers": { "type": "object", "additionalProperties": { "type": "string" } } }, "required": [ "exportJobId", "requestId", "method", "url", "expiresAt", "expiresInSeconds", "headers" ] } } } }, "400": { "description": "Invalid export download route parameters.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credential or stored API key.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Stored API key is inactive or tenant-mismatched for the export job.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Export job was not found for the credential tenant scope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "export_job_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "409": { "description": "Export job is not downloadable because it is paused, not completed, lacks an artifact, or has expired; pause reason internals are not exposed.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "export_job_paused", "export_job_not_completed", "export_artifact_missing", "export_job_expired" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Signed download URL creation failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "export_download_url_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/exports/{exportJobId}/progress": { "get": { "operationId": "getExportJobProgress", "description": "Poll a tenant-scoped export job's progress envelope. Authorize with either the configured service-token bearer credential or a tenant-bound stored API key supplied in x-api-key; stored API keys are scoped to their own tenant. Responses contain progress fields only (status, percent, rowCount) — no artifact URLs, no compliance-pause internals, no payload filters.", "security": [ { "bearerAuth": [] }, { "apiKeyHeader": [] } ], "x-api-key-placeholder": "", "parameters": [ { "name": "exportJobId", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 } }, { "name": "tenantId", "in": "query", "required": false, "description": "Optional tenant lookup scope for service credentials. Stored API keys always use the key tenant instead of this value.", "schema": { "type": "string", "minLength": 1 } } ], "responses": { "200": { "description": "Export job progress envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "exportJobId": { "type": "string" }, "requestId": { "type": "string" }, "status": { "type": "string" }, "percent": { "type": "integer", "minimum": 0, "maximum": 100 }, "rowCount": { "type": "integer", "minimum": 0 } }, "required": [ "exportJobId", "requestId", "status" ] } } } }, "400": { "description": "Invalid export progress route parameters.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credential or stored API key.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Stored API key is inactive or tenant-mismatched for the export job.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "forbidden" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Export job was not found for the credential tenant scope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "export_job_not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Export progress lookup failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "export_progress_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/devices/register": { "post": { "operationId": "postDeviceRegister", "description": "Register or update a mobile push token (APNs / FCM / WebPush) for the authenticated principal. Requires a service-token bearer credential; the body's userId + tenantId are reconciled downstream against the authenticated principal. Tokens are upserted by their globally unique value so cold-start replays are idempotent.", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "token": { "type": "string", "minLength": 1, "maxLength": 4096 }, "userId": { "type": "string", "minLength": 1, "maxLength": 128 }, "tenantId": { "type": "string", "minLength": 1, "maxLength": 128 }, "platform": { "type": "string", "enum": [ "ios", "android", "web" ] }, "provider": { "type": "string", "enum": [ "apns", "fcm", "webpush" ] }, "appVersion": { "type": "string", "maxLength": 64 } }, "required": [ "token", "userId", "platform", "provider" ] } } } }, "responses": { "200": { "description": "Push token registered (idempotent upsert).", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "deviceTokenId": { "type": "string" }, "requestId": { "type": "string" } }, "required": [ "deviceTokenId", "requestId" ] } } } }, "400": { "description": "Invalid device-register payload.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credential.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Device-token registration failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "device_register_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/devices/revoke": { "post": { "operationId": "postDeviceRevoke", "description": "Revoke a mobile push token. Requires a service-token bearer credential; the handler revokes by token hash and never echoes the raw token in the response.", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "token": { "type": "string", "minLength": 1, "maxLength": 4096 } }, "required": [ "token" ] } } } }, "responses": { "200": { "description": "Push token revoked.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "revoked": { "type": "boolean" }, "requestId": { "type": "string" } }, "required": [ "revoked", "requestId" ] } } } }, "400": { "description": "Invalid device-revoke payload.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "invalid_request" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid service credential.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Device-token revocation failed with a redacted request-ID-correlated error envelope.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "device_revoke_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/entities/{entity}": { "get": { "operationId": "getLegacyEntityByName", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "entity", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "tenantId", "in": "query", "required": false, "schema": { "type": "string", "minLength": 1 } }, { "name": "x-tenant-id", "in": "header", "required": false, "schema": { "type": "string", "minLength": 1 } }, { "name": "x-account-id", "in": "header", "required": false, "schema": { "type": "string", "minLength": 1 } } ], "responses": { "200": { "description": "Legacy-compatible entity detail graph." }, "400": { "description": "Entity lookup failed." }, "401": { "description": "Missing or invalid service credentials.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string", "enum": [ "unauthorized" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } } }, "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "service-token", "description": "Service-token credential supplied in the Authorization header with the HTTP auth scheme. Service tokens remain an alternative credential for scoped entity-row and relationship operations; documentation must not include concrete token values." }, "apiSessionBearer": { "type": "http", "scheme": "bearer", "bearerFormat": "api-session-jwt", "description": "Short-lived API session JWT returned by the login endpoint and supplied in the Authorization header for refresh and logout. Documentation must not include concrete JWT values." }, "apiKeyHeader": { "type": "apiKey", "in": "header", "name": "x-api-key", "description": "Stored tenant-bound API key supplied in the x-api-key header for scoped entity-row and relationship operations. Service-token endpoints require bearer-auth credentials in the Authorization header. Documentation must not include concrete key values." }, "mailjetWebhookAuth": { "type": "http", "scheme": "basic", "description": "HTTP Basic-Auth credentials supplied by Mailjet in the Authorization header (callback URL configured as https://mailjet:SECRET@host/...). The password is verified against MAILJET_WEBHOOK_SECRET in constant time before webhook work is queued, since Mailjet does not sign event webhooks. Documentation must not include credentials or the signing secret." }, "stripeWebhookSignature": { "type": "apiKey", "in": "header", "name": "stripe-signature", "description": "Stripe webhook signature header forwarded with the raw billing webhook payload before billing lifecycle work is processed. Documentation must not include signature values, signed payloads, or signing secrets." }, "analyticsTokenHeader": { "type": "apiKey", "in": "header", "name": "x-analytics-token", "description": "Analytics read token supplied in the x-analytics-token header for public analytics overview access. The token is configured server-side and examples must use placeholders rather than concrete credential values." } } }, "servers": [ { "url": "https://api.toolctrl.de", "description": "API host" } ] }