{ "openapi": "3.1.0", "info": { "title": "HiveGrid 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 hivegrid_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 hivegrid_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 hivegrid_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-hivegrid-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-hivegrid-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-hivegrid-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-hivegrid-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" }, "billingProviderCustomerId": { "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" }, "billingProviderCustomerId": { "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/contacts": { "get": { "operationId": "listPublicApiContacts", "description": "Tenant-scoped private-person contacts from the CRM core. Cursor-paginated, tenant-scoped and read-only. Sensitive fields are omitted instead of returning 403 for individual fields.", "security": [ { "apiKeyHeader": [] } ], "parameters": [ { "name": "x-api-key", "in": "header", "required": true, "description": "Tenant-bound API key. The key determines tenant scope; callers must not pass tenant ids in the URL.", "schema": { "type": "string", "minLength": 1 } }, { "name": "limit", "in": "query", "required": false, "description": "Page size. Defaults to 50; maximum 100.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } }, { "name": "cursor", "in": "query", "required": false, "description": "Opaque cursor returned as pageInfo.nextCursor.", "schema": { "type": "string" } }, { "name": "sort", "in": "query", "required": false, "description": "Stable cursor sort.", "schema": { "type": "string", "enum": [ "createdAt.desc", "createdAt.asc", "updatedAt.desc", "updatedAt.asc" ], "default": "createdAt.desc" } }, { "name": "fields", "in": "query", "required": false, "description": "Sparse fieldset. Supported fields: id, createdAt, updatedAt, displayName, firstName, lastName, email, phone, ownerUserId, isDemoData. The id field is always included.", "schema": { "type": "string" } }, { "name": "embed", "in": "query", "required": false, "description": "No embeds are currently supported for this resource.", "schema": { "type": "string" } }, { "name": "q", "in": "query", "required": false, "description": "Case-insensitive text filter over the resource's primary display/search fields.", "schema": { "type": "string" } }, { "name": "status", "in": "query", "required": false, "description": "Ignored for resources without status.", "schema": { "type": "string" } }, { "name": "ownerUserId", "in": "query", "required": false, "description": "Owner/assignee filter where the resource has an owner-like field.", "schema": { "type": "string" } }, { "name": "createdSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for createdAt.", "schema": { "type": "string", "format": "date-time" } }, { "name": "updatedSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for updatedAt.", "schema": { "type": "string", "format": "date-time" } } ], "responses": { "200": { "description": "Cursor-paginated contacts page.", "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": { "data": { "type": "array", "items": { "type": "object", "additionalProperties": true, "properties": { "id": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "createdAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "updatedAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "displayName": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "firstName": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "lastName": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "email": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "phone": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "ownerUserId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "isDemoData": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } } } }, "pageInfo": { "type": "object", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100 }, "nextCursor": { "type": [ "string", "null" ] }, "sort": { "type": "string" } }, "required": [ "limit", "nextCursor", "sort" ] }, "meta": { "type": "object", "properties": { "resource": { "type": "string", "enum": [ "contacts" ] }, "readOnly": { "type": "boolean", "const": true }, "requestId": { "type": "string" } }, "required": [ "resource", "readOnly", "requestId" ] } }, "required": [ "data", "pageInfo", "meta" ] } } } }, "400": { "description": "Invalid list query.", "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_limit", "invalid_cursor", "invalid_sort", "invalid_fields", "invalid_embed", "invalid_status", "invalid_created_since", "invalid_updated_since" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid 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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "402": { "description": "API usage is disabled or exhausted for the tenant plan.", "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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Tenant is inactive or the API key scope does not allow 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": [ "tenant_inactive", "insufficient_scope" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "429": { "description": "Hourly key or tenant rate limit exceeded.", "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_limit_exceeded" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Read request failed with a redacted request-ID-correlated 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": [ "public_api_read_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/companies": { "get": { "operationId": "listPublicApiCompanies", "description": "Tenant-scoped organisation contacts from the CRM core. Cursor-paginated, tenant-scoped and read-only. Sensitive fields are omitted instead of returning 403 for individual fields.", "security": [ { "apiKeyHeader": [] } ], "parameters": [ { "name": "x-api-key", "in": "header", "required": true, "description": "Tenant-bound API key. The key determines tenant scope; callers must not pass tenant ids in the URL.", "schema": { "type": "string", "minLength": 1 } }, { "name": "limit", "in": "query", "required": false, "description": "Page size. Defaults to 50; maximum 100.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } }, { "name": "cursor", "in": "query", "required": false, "description": "Opaque cursor returned as pageInfo.nextCursor.", "schema": { "type": "string" } }, { "name": "sort", "in": "query", "required": false, "description": "Stable cursor sort.", "schema": { "type": "string", "enum": [ "createdAt.desc", "createdAt.asc", "updatedAt.desc", "updatedAt.asc" ], "default": "createdAt.desc" } }, { "name": "fields", "in": "query", "required": false, "description": "Sparse fieldset. Supported fields: id, createdAt, updatedAt, name, legalForm, email, phone, ownerUserId, isDemoData. The id field is always included.", "schema": { "type": "string" } }, { "name": "embed", "in": "query", "required": false, "description": "No embeds are currently supported for this resource.", "schema": { "type": "string" } }, { "name": "q", "in": "query", "required": false, "description": "Case-insensitive text filter over the resource's primary display/search fields.", "schema": { "type": "string" } }, { "name": "status", "in": "query", "required": false, "description": "Ignored for resources without status.", "schema": { "type": "string" } }, { "name": "ownerUserId", "in": "query", "required": false, "description": "Owner/assignee filter where the resource has an owner-like field.", "schema": { "type": "string" } }, { "name": "createdSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for createdAt.", "schema": { "type": "string", "format": "date-time" } }, { "name": "updatedSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for updatedAt.", "schema": { "type": "string", "format": "date-time" } } ], "responses": { "200": { "description": "Cursor-paginated companies page.", "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": { "data": { "type": "array", "items": { "type": "object", "additionalProperties": true, "properties": { "id": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "createdAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "updatedAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "name": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "legalForm": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "email": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "phone": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "ownerUserId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "isDemoData": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } } } }, "pageInfo": { "type": "object", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100 }, "nextCursor": { "type": [ "string", "null" ] }, "sort": { "type": "string" } }, "required": [ "limit", "nextCursor", "sort" ] }, "meta": { "type": "object", "properties": { "resource": { "type": "string", "enum": [ "companies" ] }, "readOnly": { "type": "boolean", "const": true }, "requestId": { "type": "string" } }, "required": [ "resource", "readOnly", "requestId" ] } }, "required": [ "data", "pageInfo", "meta" ] } } } }, "400": { "description": "Invalid list query.", "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_limit", "invalid_cursor", "invalid_sort", "invalid_fields", "invalid_embed", "invalid_status", "invalid_created_since", "invalid_updated_since" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid 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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "402": { "description": "API usage is disabled or exhausted for the tenant plan.", "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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Tenant is inactive or the API key scope does not allow 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": [ "tenant_inactive", "insufficient_scope" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "429": { "description": "Hourly key or tenant rate limit exceeded.", "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_limit_exceeded" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Read request failed with a redacted request-ID-correlated 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": [ "public_api_read_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/deals": { "get": { "operationId": "listPublicApiDeals", "description": "Sales-pipeline project view. Deals and projects share the Projekt core. Cursor-paginated, tenant-scoped and read-only. Sensitive fields are omitted instead of returning 403 for individual fields.", "security": [ { "apiKeyHeader": [] } ], "parameters": [ { "name": "x-api-key", "in": "header", "required": true, "description": "Tenant-bound API key. The key determines tenant scope; callers must not pass tenant ids in the URL.", "schema": { "type": "string", "minLength": 1 } }, { "name": "limit", "in": "query", "required": false, "description": "Page size. Defaults to 50; maximum 100.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } }, { "name": "cursor", "in": "query", "required": false, "description": "Opaque cursor returned as pageInfo.nextCursor.", "schema": { "type": "string" } }, { "name": "sort", "in": "query", "required": false, "description": "Stable cursor sort.", "schema": { "type": "string", "enum": [ "createdAt.desc", "createdAt.asc", "updatedAt.desc", "updatedAt.asc" ], "default": "createdAt.desc" } }, { "name": "fields", "in": "query", "required": false, "description": "Sparse fieldset. Supported fields: id, createdAt, updatedAt, number, name, description, pipelineId, stageId, potentialValue, orderVolume, ownerUserId, projectLeadUserId, wonAt, lostAt, isDemoData. The id field is always included.", "schema": { "type": "string" } }, { "name": "embed", "in": "query", "required": false, "description": "Comma-separated depth-1 embeds. Supported embeds: pipeline, stage.", "schema": { "type": "string" } }, { "name": "q", "in": "query", "required": false, "description": "Case-insensitive text filter over the resource's primary display/search fields.", "schema": { "type": "string" } }, { "name": "status", "in": "query", "required": false, "description": "Ignored for resources without status.", "schema": { "type": "string" } }, { "name": "ownerUserId", "in": "query", "required": false, "description": "Owner/assignee filter where the resource has an owner-like field.", "schema": { "type": "string" } }, { "name": "createdSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for createdAt.", "schema": { "type": "string", "format": "date-time" } }, { "name": "updatedSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for updatedAt.", "schema": { "type": "string", "format": "date-time" } } ], "responses": { "200": { "description": "Cursor-paginated deals page.", "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": { "data": { "type": "array", "items": { "type": "object", "additionalProperties": true, "properties": { "id": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "createdAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "updatedAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "number": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "name": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "description": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "pipelineId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "stageId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "potentialValue": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "orderVolume": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "ownerUserId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "projectLeadUserId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "wonAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "lostAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "isDemoData": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } } } }, "pageInfo": { "type": "object", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100 }, "nextCursor": { "type": [ "string", "null" ] }, "sort": { "type": "string" } }, "required": [ "limit", "nextCursor", "sort" ] }, "meta": { "type": "object", "properties": { "resource": { "type": "string", "enum": [ "deals" ] }, "readOnly": { "type": "boolean", "const": true }, "requestId": { "type": "string" } }, "required": [ "resource", "readOnly", "requestId" ] } }, "required": [ "data", "pageInfo", "meta" ] } } } }, "400": { "description": "Invalid list query.", "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_limit", "invalid_cursor", "invalid_sort", "invalid_fields", "invalid_embed", "invalid_status", "invalid_created_since", "invalid_updated_since" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid 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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "402": { "description": "API usage is disabled or exhausted for the tenant plan.", "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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Tenant is inactive or the API key scope does not allow 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": [ "tenant_inactive", "insufficient_scope" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "429": { "description": "Hourly key or tenant rate limit exceeded.", "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_limit_exceeded" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Read request failed with a redacted request-ID-correlated 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": [ "public_api_read_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/projects": { "get": { "operationId": "listPublicApiProjects", "description": "Tenant-scoped project records from the Projekt core. Cursor-paginated, tenant-scoped and read-only. Sensitive fields are omitted instead of returning 403 for individual fields.", "security": [ { "apiKeyHeader": [] } ], "parameters": [ { "name": "x-api-key", "in": "header", "required": true, "description": "Tenant-bound API key. The key determines tenant scope; callers must not pass tenant ids in the URL.", "schema": { "type": "string", "minLength": 1 } }, { "name": "limit", "in": "query", "required": false, "description": "Page size. Defaults to 50; maximum 100.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } }, { "name": "cursor", "in": "query", "required": false, "description": "Opaque cursor returned as pageInfo.nextCursor.", "schema": { "type": "string" } }, { "name": "sort", "in": "query", "required": false, "description": "Stable cursor sort.", "schema": { "type": "string", "enum": [ "createdAt.desc", "createdAt.asc", "updatedAt.desc", "updatedAt.asc" ], "default": "createdAt.desc" } }, { "name": "fields", "in": "query", "required": false, "description": "Sparse fieldset. Supported fields: id, createdAt, updatedAt, number, name, description, type, source, priority, pipelineId, stageId, potentialValue, orderVolume, startDate, deadline, ownerUserId, projectLeadUserId, convertedFromLeadId, wonAt, lostAt, isDemoData. The id field is always included.", "schema": { "type": "string" } }, { "name": "embed", "in": "query", "required": false, "description": "Comma-separated depth-1 embeds. Supported embeds: pipeline, stage.", "schema": { "type": "string" } }, { "name": "q", "in": "query", "required": false, "description": "Case-insensitive text filter over the resource's primary display/search fields.", "schema": { "type": "string" } }, { "name": "status", "in": "query", "required": false, "description": "Ignored for resources without status.", "schema": { "type": "string" } }, { "name": "ownerUserId", "in": "query", "required": false, "description": "Owner/assignee filter where the resource has an owner-like field.", "schema": { "type": "string" } }, { "name": "createdSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for createdAt.", "schema": { "type": "string", "format": "date-time" } }, { "name": "updatedSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for updatedAt.", "schema": { "type": "string", "format": "date-time" } } ], "responses": { "200": { "description": "Cursor-paginated projects page.", "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": { "data": { "type": "array", "items": { "type": "object", "additionalProperties": true, "properties": { "id": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "createdAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "updatedAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "number": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "name": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "description": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "type": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "source": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "priority": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "pipelineId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "stageId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "potentialValue": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "orderVolume": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "startDate": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "deadline": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "ownerUserId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "projectLeadUserId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "convertedFromLeadId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "wonAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "lostAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "isDemoData": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } } } }, "pageInfo": { "type": "object", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100 }, "nextCursor": { "type": [ "string", "null" ] }, "sort": { "type": "string" } }, "required": [ "limit", "nextCursor", "sort" ] }, "meta": { "type": "object", "properties": { "resource": { "type": "string", "enum": [ "projects" ] }, "readOnly": { "type": "boolean", "const": true }, "requestId": { "type": "string" } }, "required": [ "resource", "readOnly", "requestId" ] } }, "required": [ "data", "pageInfo", "meta" ] } } } }, "400": { "description": "Invalid list query.", "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_limit", "invalid_cursor", "invalid_sort", "invalid_fields", "invalid_embed", "invalid_status", "invalid_created_since", "invalid_updated_since" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid 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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "402": { "description": "API usage is disabled or exhausted for the tenant plan.", "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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Tenant is inactive or the API key scope does not allow 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": [ "tenant_inactive", "insufficient_scope" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "429": { "description": "Hourly key or tenant rate limit exceeded.", "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_limit_exceeded" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Read request failed with a redacted request-ID-correlated 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": [ "public_api_read_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/tasks": { "get": { "operationId": "listPublicApiTasks", "description": "Tenant-scoped task records. Cursor-paginated, tenant-scoped and read-only. Sensitive fields are omitted instead of returning 403 for individual fields.", "security": [ { "apiKeyHeader": [] } ], "parameters": [ { "name": "x-api-key", "in": "header", "required": true, "description": "Tenant-bound API key. The key determines tenant scope; callers must not pass tenant ids in the URL.", "schema": { "type": "string", "minLength": 1 } }, { "name": "limit", "in": "query", "required": false, "description": "Page size. Defaults to 50; maximum 100.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } }, { "name": "cursor", "in": "query", "required": false, "description": "Opaque cursor returned as pageInfo.nextCursor.", "schema": { "type": "string" } }, { "name": "sort", "in": "query", "required": false, "description": "Stable cursor sort.", "schema": { "type": "string", "enum": [ "createdAt.desc", "createdAt.asc", "updatedAt.desc", "updatedAt.asc" ], "default": "createdAt.desc" } }, { "name": "fields", "in": "query", "required": false, "description": "Sparse fieldset. Supported fields: id, createdAt, updatedAt, title, description, status, priority, deadline, assignedToUserId, assignedToGroupId, linkedEntityType, linkedEntityId, source, completedAt, isDemoData. The id field is always included.", "schema": { "type": "string" } }, { "name": "embed", "in": "query", "required": false, "description": "No embeds are currently supported for this resource.", "schema": { "type": "string" } }, { "name": "q", "in": "query", "required": false, "description": "Case-insensitive text filter over the resource's primary display/search fields.", "schema": { "type": "string" } }, { "name": "status", "in": "query", "required": false, "description": "Status filter. Supported values: open, in_progress, blocked, done, cancelled.", "schema": { "type": "string", "enum": [ "open", "in_progress", "blocked", "done", "cancelled" ] } }, { "name": "ownerUserId", "in": "query", "required": false, "description": "Owner/assignee filter where the resource has an owner-like field.", "schema": { "type": "string" } }, { "name": "createdSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for createdAt.", "schema": { "type": "string", "format": "date-time" } }, { "name": "updatedSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for updatedAt.", "schema": { "type": "string", "format": "date-time" } } ], "responses": { "200": { "description": "Cursor-paginated tasks page.", "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": { "data": { "type": "array", "items": { "type": "object", "additionalProperties": true, "properties": { "id": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "createdAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "updatedAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "title": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "description": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "status": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "priority": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "deadline": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "assignedToUserId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "assignedToGroupId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "linkedEntityType": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "linkedEntityId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "source": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "completedAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "isDemoData": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } } } }, "pageInfo": { "type": "object", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100 }, "nextCursor": { "type": [ "string", "null" ] }, "sort": { "type": "string" } }, "required": [ "limit", "nextCursor", "sort" ] }, "meta": { "type": "object", "properties": { "resource": { "type": "string", "enum": [ "tasks" ] }, "readOnly": { "type": "boolean", "const": true }, "requestId": { "type": "string" } }, "required": [ "resource", "readOnly", "requestId" ] } }, "required": [ "data", "pageInfo", "meta" ] } } } }, "400": { "description": "Invalid list query.", "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_limit", "invalid_cursor", "invalid_sort", "invalid_fields", "invalid_embed", "invalid_status", "invalid_created_since", "invalid_updated_since" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid 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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "402": { "description": "API usage is disabled or exhausted for the tenant plan.", "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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Tenant is inactive or the API key scope does not allow 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": [ "tenant_inactive", "insufficient_scope" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "429": { "description": "Hourly key or tenant rate limit exceeded.", "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_limit_exceeded" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Read request failed with a redacted request-ID-correlated 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": [ "public_api_read_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/leads": { "get": { "operationId": "listPublicApiLeads", "description": "Tenant-scoped lead-inbox records. Cursor-paginated, tenant-scoped and read-only. Sensitive fields are omitted instead of returning 403 for individual fields.", "security": [ { "apiKeyHeader": [] } ], "parameters": [ { "name": "x-api-key", "in": "header", "required": true, "description": "Tenant-bound API key. The key determines tenant scope; callers must not pass tenant ids in the URL.", "schema": { "type": "string", "minLength": 1 } }, { "name": "limit", "in": "query", "required": false, "description": "Page size. Defaults to 50; maximum 100.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } }, { "name": "cursor", "in": "query", "required": false, "description": "Opaque cursor returned as pageInfo.nextCursor.", "schema": { "type": "string" } }, { "name": "sort", "in": "query", "required": false, "description": "Stable cursor sort.", "schema": { "type": "string", "enum": [ "createdAt.desc", "createdAt.asc", "updatedAt.desc", "updatedAt.asc" ], "default": "createdAt.desc" } }, { "name": "fields", "in": "query", "required": false, "description": "Sparse fieldset. Supported fields: id, createdAt, updatedAt, source, sourceOrigin, status, firstName, lastName, email, phone, message, ownerUserId, linkedContactId, convertedProjectId, convertedAt, isDemoData. The id field is always included.", "schema": { "type": "string" } }, { "name": "embed", "in": "query", "required": false, "description": "Comma-separated depth-1 embeds. Supported embeds: leadSource.", "schema": { "type": "string" } }, { "name": "q", "in": "query", "required": false, "description": "Case-insensitive text filter over the resource's primary display/search fields.", "schema": { "type": "string" } }, { "name": "status", "in": "query", "required": false, "description": "Status filter. Supported values: new, qualified, converted, lost, spam.", "schema": { "type": "string", "enum": [ "new", "qualified", "converted", "lost", "spam" ] } }, { "name": "ownerUserId", "in": "query", "required": false, "description": "Owner/assignee filter where the resource has an owner-like field.", "schema": { "type": "string" } }, { "name": "createdSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for createdAt.", "schema": { "type": "string", "format": "date-time" } }, { "name": "updatedSince", "in": "query", "required": false, "description": "Inclusive ISO date-time lower bound for updatedAt.", "schema": { "type": "string", "format": "date-time" } } ], "responses": { "200": { "description": "Cursor-paginated leads page.", "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": { "data": { "type": "array", "items": { "type": "object", "additionalProperties": true, "properties": { "id": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "createdAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "updatedAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "source": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "sourceOrigin": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "status": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "firstName": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "lastName": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "email": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "phone": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "message": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "ownerUserId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "linkedContactId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "convertedProjectId": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "convertedAt": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] }, "isDemoData": { "oneOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" } ] } } } }, "pageInfo": { "type": "object", "properties": { "limit": { "type": "integer", "minimum": 1, "maximum": 100 }, "nextCursor": { "type": [ "string", "null" ] }, "sort": { "type": "string" } }, "required": [ "limit", "nextCursor", "sort" ] }, "meta": { "type": "object", "properties": { "resource": { "type": "string", "enum": [ "leads" ] }, "readOnly": { "type": "boolean", "const": true }, "requestId": { "type": "string" } }, "required": [ "resource", "readOnly", "requestId" ] } }, "required": [ "data", "pageInfo", "meta" ] } } } }, "400": { "description": "Invalid list query.", "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_limit", "invalid_cursor", "invalid_sort", "invalid_fields", "invalid_embed", "invalid_status", "invalid_created_since", "invalid_updated_since" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid 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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "402": { "description": "API usage is disabled or exhausted for the tenant plan.", "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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "Tenant is inactive or the API key scope does not allow 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": [ "tenant_inactive", "insufficient_scope" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "429": { "description": "Hourly key or tenant rate limit exceeded.", "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_limit_exceeded" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Read request failed with a redacted request-ID-correlated 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": [ "public_api_read_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/webhooks/incoming/{tenant}/{slug}": { "post": { "operationId": "receivePublicApiIncomingWebhook", "description": "Tenant-scoped incoming lead webhook. The endpoint authenticates by the endpoint's configured mode: API key, HMAC token/signature, or URL/header token. Successful requests create an InboxLead and queue webhook.received automation executions.", "security": [ { "apiKeyHeader": [] }, { "webhookTokenHeader": [] }, { "webhookHmac": [] } ], "parameters": [ { "name": "tenant", "in": "path", "required": true, "description": "Tenant id or slug addressed by the incoming webhook endpoint.", "schema": { "type": "string", "minLength": 1 } }, { "name": "slug", "in": "path", "required": true, "description": "Tenant-local incoming webhook endpoint slug.", "schema": { "type": "string", "minLength": 1 } }, { "name": "x-api-key", "in": "header", "required": false, "description": "Required when the endpoint auth mode is api_key. The key must include public_api:webhooks:incoming, public_api:read legacy scope does not grant writes.", "schema": { "type": "string" } }, { "name": "X-HiveGrid-Webhook-Token", "in": "header", "required": false, "description": "Required for hmac and url_token endpoint modes. For hmac, this presented token is also the HMAC key and is validated against the stored hash.", "schema": { "type": "string" } }, { "name": "X-HiveGrid-Timestamp", "in": "header", "required": false, "description": "Unix timestamp used in the HMAC signing input '.'. Required for hmac endpoint mode.", "schema": { "type": "string" } }, { "name": "X-HiveGrid-Signature", "in": "header", "required": false, "description": "HMAC-SHA256 signature in the form sha256=. Required for hmac endpoint mode.", "schema": { "type": "string" } }, { "name": "token", "in": "query", "required": false, "description": "Alternative token transport for url_token endpoints.", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true, "description": "Lead payload. Payload mapping on the endpoint selects fields such as email, phone, firstName, lastName and message." } } } }, "responses": { "201": { "description": "Lead webhook accepted and persisted.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } }, "X-RateLimit-Limit": { "schema": { "type": "string" } }, "X-RateLimit-Remaining": { "schema": { "type": "string" } }, "X-RateLimit-Reset": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "leadId": { "type": "string" }, "matchedKontaktId": { "type": [ "string", "null" ] }, "automationExecutionIds": { "type": "array", "items": { "type": "string" } } }, "required": [ "leadId", "matchedKontaktId", "automationExecutionIds" ] }, "meta": { "type": "object", "properties": { "requestId": { "type": "string" }, "endpoint": { "type": "string" } }, "required": [ "requestId", "endpoint" ] } }, "required": [ "data", "meta" ] } } } }, "400": { "description": "Invalid JSON 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_json" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or invalid webhook 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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "402": { "description": "Tenant plan or billing state blocks webhook writes.", "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": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "403": { "description": "API key scope does not allow incoming webhooks.", "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": [ "insufficient_scope" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "404": { "description": "Tenant or incoming webhook endpoint 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": [ "not_found" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "429": { "description": "Hourly key or tenant rate limit exceeded.", "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_limit_exceeded" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } }, "500": { "description": "Webhook ingestion failed with a redacted request-ID-correlated 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": [ "webhook_ingestion_failed" ] }, "message": { "type": "string" }, "params": { "type": "object", "additionalProperties": true }, "requestId": { "type": "string" } }, "required": [ "code", "message", "requestId" ] } }, "required": [ "error" ] } } } } } } }, "/v1/billing/mollie/webhooks": { "post": { "operationId": "receiveMollieBillingWebhook", "description": "Canonical API-host entry point for Mollie payment lifecycle webhooks. Mollie posts a payment id; the API refetches that payment from Mollie server-side before syncing tenant billing state.", "security": [], "requestBody": { "required": true, "content": { "application/x-www-form-urlencoded": { "schema": { "type": "object", "properties": { "id": { "type": "string", "minLength": 1, "description": "Mollie payment id supplied by the provider webhook." } }, "required": [ "id" ] } } } }, "responses": { "200": { "description": "Webhook accepted after provider-side payment verification and billing sync.", "headers": { "x-request-id": { "description": "Request correlation identifier echoed from the request or generated by the API.", "schema": { "type": "string" } } } }, "400": { "description": "Missing, invalid, or unmappable Mollie 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", "invalid_provider_payload" ] }, "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": "Mollie payment id could not be verified against the provider API.", "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": [ "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" ] } } } }, "503": { "description": "Mollie billing webhook configuration is unavailable or provider verification failed before any billing write.", "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": [ "dependency_unavailable", "provider_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/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/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 Web Push token 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": [ "web" ] }, "provider": { "type": "string", "enum": [ "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 Web 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" ] } } } } } } } }, "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." }, "webhookTokenHeader": { "type": "apiKey", "in": "header", "name": "X-HiveGrid-Webhook-Token", "description": "Tenant incoming-webhook token supplied in the X-HiveGrid-Webhook-Token header. The API stores only a hash of this token and never returns it after creation." }, "webhookHmac": { "type": "apiKey", "in": "header", "name": "X-HiveGrid-Signature", "description": "HMAC-SHA256 signature header for incoming webhooks. The signing input is '.' and the credential is the presented webhook token, which is validated against the stored hash." }, "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." }, "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.hivegrid.de", "description": "API host" } ] }