{
  "openapi": "3.0.3",
  "info": {
    "title": "Portal Partner API",
    "version": "1.0.0",
    "description": "Portal-owned server-to-server API. Create an integration key in Settings → Developer. Keys are account-wide; assessments managed here must originate from this API. A new permanent report consumes one Portal credit; assessments and report reads do not. No email or public sharing is triggered. Set the server to the Portal backend origin supplied for your environment; product Portal v2 and endpoint /partner/v1 are different version labels."
  },
  "servers": [
    {
      "url": "{origin}/partner/v1",
      "variables": {
        "origin": {
          "default": "https://YOUR_PORTAL_API_HOST",
          "description": "Replace with your configured Portal backend origin. This placeholder is not a live API host."
        }
      }
    }
  ],
  "security": [
    {
      "PortalKey": []
    }
  ],
  "paths": {
    "/status": {
      "get": {
        "operationId": "status",
        "summary": "Check connection",
        "x-required-scope": "connection:read",
        "description": "Required scope: connection:read. All responses use Cache-Control: no-store.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success or idempotent replay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Connection"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/participants": {
      "put": {
        "operationId": "participant",
        "summary": "Create or update a client",
        "x-required-scope": "participants:write",
        "description": "Required scope: participants:write. All responses use Cache-Control: no-store.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success or idempotent replay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParticipantResponse"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParticipantResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "State or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Processing failed; retry with the same ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ParticipantInput"
              },
              "example": {
                "fullName": "Alex Example",
                "email": "alex@example.test",
                "locale": "en",
                "externalId": "customer-123"
              }
            }
          }
        }
      }
    },
    "/assessments": {
      "post": {
        "operationId": "createAssessment",
        "summary": "Create an assessment",
        "x-required-scope": "assessments:write",
        "description": "Required scope: assessments:write. All responses use Cache-Control: no-store.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9:_-]{8,128}$"
            },
            "description": "Keep the same value and body for retries. A different operation must use its own key."
          }
        ],
        "responses": {
          "200": {
            "description": "Success or idempotent replay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssessmentResponse"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssessmentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "State or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Processing failed; retry with the same ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssessmentInput"
              },
              "example": {
                "participantId": "PARTICIPANTID",
                "locale": "en",
                "expiresAt": "2026-12-01T00:00:00Z"
              }
            }
          }
        }
      }
    },
    "/assessments/{assessmentId}/questions": {
      "get": {
        "operationId": "questions",
        "summary": "Get the questionnaire",
        "x-required-scope": "assessments:read",
        "description": "Required scope: assessments:read. All responses use Cache-Control: no-store.",
        "parameters": [
          {
            "name": "assessmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9:_-]{1,128}$",
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success or idempotent replay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Questions"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Expired assessment or revoked report",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Processing failed; retry with the same ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/assessments/{assessmentId}/answers": {
      "put": {
        "operationId": "answers",
        "summary": "Save answers",
        "x-required-scope": "assessments:write",
        "description": "Required scope: assessments:write. All responses use Cache-Control: no-store.",
        "parameters": [
          {
            "name": "assessmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9:_-]{1,128}$",
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success or idempotent replay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedAnswers"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "State or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Expired assessment or revoked report",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Processing failed; retry with the same ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnswersInput"
              }
            }
          }
        }
      }
    },
    "/assessments/{assessmentId}/complete": {
      "post": {
        "operationId": "complete",
        "summary": "Complete an assessment",
        "x-required-scope": "assessments:write",
        "description": "Required scope: assessments:write. All responses use Cache-Control: no-store.",
        "parameters": [
          {
            "name": "assessmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9:_-]{1,128}$",
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success or idempotent replay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultResponse"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "State or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Expired assessment or revoked report",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Processing failed; retry with the same ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmptyInput"
              },
              "example": {}
            }
          }
        }
      }
    },
    "/assessments/{assessmentId}": {
      "get": {
        "operationId": "assessment",
        "summary": "Read assessment progress",
        "x-required-scope": "assessments:read",
        "description": "Required scope: assessments:read. All responses use Cache-Control: no-store.",
        "parameters": [
          {
            "name": "assessmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9:_-]{1,128}$",
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success or idempotent replay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssessmentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Processing failed; retry with the same ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/credits": {
      "get": {
        "operationId": "credits",
        "summary": "Check credit balance",
        "x-required-scope": "credits:read",
        "description": "Required scope: credits:read. All responses use Cache-Control: no-store.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success or idempotent replay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Credits"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Processing failed; retry with the same ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/reports": {
      "post": {
        "operationId": "createReport",
        "summary": "Generate a permanent report (1 credit)",
        "x-required-scope": "reports:write",
        "description": "Required scope: reports:write. All responses use Cache-Control: no-store.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9:_-]{8,128}$"
            },
            "description": "Keep the same value and body for retries. A different operation must use its own key."
          }
        ],
        "responses": {
          "200": {
            "description": "Success or idempotent replay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportResponse"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits; retry after topping up with the same request ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "State or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Expired assessment or revoked report",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 32 KiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Processing failed; retry with the same ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportInput"
              },
              "example": {
                "assessmentResultId": "ASSESSMENTRESULTID"
              }
            }
          }
        }
      }
    },
    "/reports/{reportId}": {
      "get": {
        "operationId": "report",
        "summary": "Read a full report",
        "x-required-scope": "reports:read",
        "description": "Required scope: reports:read. All responses use Cache-Control: no-store.",
        "parameters": [
          {
            "name": "reportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9:_-]{1,128}$",
              "maxLength": 128
            }
          },
          {
            "name": "locale",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "ar",
                "es"
              ]
            },
            "description": "Read-only view language; defaults to the saved report locale."
          }
        ],
        "responses": {
          "200": {
            "description": "Success or idempotent replay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, expired or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; Retry-After: 60",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Processing failed; retry with the same ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "PortalKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Server-held key. No X-Provider header. Never put a key in browser/mobile code."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "code": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "code"
        ]
      },
      "Connection": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "accountId": {
            "type": "string"
          },
          "keyId": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "ok",
          "accountId",
          "keyId",
          "scopes"
        ]
      },
      "ParticipantInput": {
        "type": "object",
        "properties": {
          "fullName": {
            "type": "string",
            "maxLength": 160,
            "minLength": 1
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "locale": {
            "type": "string",
            "enum": [
              "en",
              "ar",
              "es"
            ]
          },
          "externalId": {
            "type": "string",
            "maxLength": 128
          }
        },
        "required": [
          "fullName",
          "email",
          "locale"
        ],
        "additionalProperties": false
      },
      "ParticipantResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "created": {
            "type": "boolean"
          },
          "participant": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "fullName": {
                "type": "string"
              },
              "email": {
                "type": "string"
              },
              "locale": {
                "type": "string",
                "enum": [
                  "en",
                  "ar",
                  "es"
                ]
              },
              "externalId": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "fullName",
              "email",
              "locale"
            ]
          }
        },
        "required": [
          "ok",
          "created",
          "participant"
        ]
      },
      "AssessmentInput": {
        "type": "object",
        "properties": {
          "participantId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9:_-]{1,128}$",
            "maxLength": 128
          },
          "locale": {
            "type": "string",
            "enum": [
              "en",
              "ar",
              "es"
            ]
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "Future UTC timestamp, at most 180 days after creation."
          }
        },
        "required": [
          "participantId",
          "locale",
          "expiresAt"
        ],
        "additionalProperties": false
      },
      "AssessmentResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "idempotent": {
            "type": "boolean"
          },
          "assessment": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "participantId": {
                "type": "string"
              },
              "locale": {
                "type": "string",
                "enum": [
                  "en",
                  "ar",
                  "es"
                ]
              },
              "status": {
                "type": "string",
                "enum": [
                  "invited",
                  "in_progress",
                  "completed",
                  "expired"
                ]
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              },
              "assessmentResultId": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "participantId",
              "locale",
              "status",
              "expiresAt"
            ]
          }
        },
        "required": [
          "ok",
          "assessment"
        ]
      },
      "Questions": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "locale": {
            "type": "string",
            "enum": [
              "en",
              "ar",
              "es"
            ]
          },
          "questionnaireVersion": {
            "type": "string"
          },
          "totalQuestions": {
            "type": "integer",
            "enum": [
              120
            ]
          },
          "items": {
            "type": "array",
            "minItems": 120,
            "maxItems": 120,
            "items": {
              "type": "object",
              "properties": {
                "questionId": {
                  "type": "string"
                },
                "number": {
                  "type": "integer"
                },
                "text": {
                  "type": "string"
                },
                "choices": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "value": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 5
                      },
                      "text": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "value",
                      "text"
                    ]
                  }
                }
              },
              "required": [
                "questionId",
                "number",
                "text",
                "choices"
              ]
            }
          }
        },
        "required": [
          "ok",
          "locale",
          "questionnaireVersion",
          "totalQuestions",
          "items"
        ]
      },
      "AnswersInput": {
        "type": "object",
        "properties": {
          "answers": {
            "type": "array",
            "minItems": 1,
            "maxItems": 120,
            "description": "Use actual returned question IDs and participant answers; IDs must be unique within the request.",
            "items": {
              "type": "object",
              "properties": {
                "questionId": {
                  "type": "string"
                },
                "value": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 5
                }
              },
              "required": [
                "questionId",
                "value"
              ]
            }
          }
        },
        "required": [
          "answers"
        ],
        "additionalProperties": false
      },
      "SavedAnswers": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "savedCount": {
            "type": "integer"
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "ok",
          "savedCount",
          "status"
        ]
      },
      "EmptyInput": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      },
      "ResultResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "idempotent": {
            "type": "boolean"
          },
          "result": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "sessionId": {
                "type": "string"
              },
              "scoringVersion": {
                "type": "string"
              },
              "completedAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "required": [
              "id",
              "sessionId",
              "scoringVersion",
              "completedAt"
            ]
          }
        },
        "required": [
          "ok",
          "idempotent",
          "result"
        ]
      },
      "ReportInput": {
        "type": "object",
        "properties": {
          "assessmentResultId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9:_-]{1,128}$",
            "maxLength": 128
          }
        },
        "required": [
          "assessmentResultId"
        ],
        "additionalProperties": false
      },
      "ReportResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "idempotent": {
            "type": "boolean"
          },
          "report": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "assessmentResultId": {
                "type": "string"
              },
              "participantId": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "ready"
                ]
              },
              "locale": {
                "type": "string",
                "enum": [
                  "en",
                  "ar",
                  "es"
                ]
              },
              "algorithmVersion": {
                "type": "string"
              },
              "generatedAt": {
                "type": "string",
                "format": "date-time"
              },
              "report": {
                "type": "object",
                "additionalProperties": true,
                "description": "Saved Portal full report with the same approved localized presentation as the owner dashboard. Treat algorithmVersion and contentVersion as versioned data; no fixed metric count is promised."
              }
            },
            "required": [
              "id",
              "assessmentResultId",
              "participantId",
              "status",
              "locale",
              "algorithmVersion",
              "report"
            ]
          }
        },
        "required": [
          "ok",
          "report"
        ]
      },
      "Credits": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "asOf": {
            "type": "string",
            "format": "date-time"
          },
          "balance": {
            "type": "object",
            "properties": {
              "available": {
                "type": "integer"
              },
              "reserved": {
                "type": "integer"
              },
              "unspent": {
                "type": "integer"
              },
              "debt": {
                "type": "integer"
              },
              "onHold": {
                "type": "boolean"
              }
            },
            "required": [
              "available",
              "reserved",
              "unspent",
              "debt",
              "onHold"
            ]
          }
        },
        "required": [
          "ok",
          "asOf",
          "balance"
        ]
      }
    }
  }
}
