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