{
  "openapi": "3.0.3",
  "info": {
    "title": "VerityPro API",
    "version": "2.2.0",
    "description": "VerityPro public API — KYC, Address, EDD, AML Transaction Monitoring, and the embedded Web SDK (v2).\n\n> **Status note (2026-08-31):** The v2 embed flow (`/hosted-verify` + embed token) is in production-readiness review. The bearer-auth scheme for browser-side v2 calls is implemented in the hosted SDK but is **not yet accepted on all backend v2 endpoints** in production — the production gate still requires the API key on session-read and step operations. Use the legacy v1 flow (`add-kyc-verification` + sessionUrl) for live production integrations until the bearer deployment is confirmed. This spec documents the target contract.\n\n## Authentication\n\nServer-to-server (S2S) calls require **both** headers:\n- `x-api-key` — your integration API key\n- `Integrationid` — the UUID of your integration (must match the key)\n\nBrowser-side v2 calls carry a short-lived **Bearer token** obtained by exchanging an embed token. See status note above for current production availability.\n\n## Hosted Verification — Embed Flow (target architecture)\n\n1. **Your backend (S2S)** calls `POST /kycintegration/v2/embed/mint` with the user's details and your `allowedParentOrigin`. The backend creates the session at mint time and receives a one-time `embedToken` (5 min TTL).\n2. **Your frontend** passes the token to the VerityPro Web SDK: `mount({ baseUrl, embedToken, onResult })`. The SDK iframes `/hosted-verify#token=<embedToken>` (URL fragment — never logged by CDN or WAF).\n3. The **browser** exchanges the token for a short-lived in-memory bearer via `POST /kycintegration/v2/embed/exchange`. The bearer lives only in a JS module closure — never `localStorage` or `sessionStorage`.\n   > **Origin note:** `allowedParentOrigin` is the origin of your **embedding web application** (e.g. `https://yourapp.com`). The SDK uses this value for postMessage target-origin enforcement — it never broadcasts to `'*'`. The token exchange is performed by the hosted verification page running in the iframe; the exchange-origin check validates the request `Origin` against the deployment's registered hosted-verification domain (a server-side constant), not against `allowedParentOrigin`. Do **not** set `allowedParentOrigin` to the hosted verification origin — it is your parent application's origin only.\n4. The SDK fires `onResult({ status: 'approved' | 'rejected' | … })` when the user completes verification.\n5. Your **backend** confirms the authoritative result via `GET /kycintegration/v2/sessions/{id}` (S2S, API key) or the webhook.\n\n## Deployment prerequisite for embedding\n\nThe `/hosted-verify` page ships with `Content-Security-Policy: frame-ancestors 'self'` by default. External integrators must have `VERIFY_ALLOWED_FRAME_ANCESTORS` set to their registered origin on the deployment. Contact your VerityPro account manager to register allowed origins before going live.\n\nSee the [Web SDK README](https://github.com/VerityPro/veritypro-web-sdk) for framework samples."
  },
  "servers": [
    {
      "url": "https://api.skylinefare.com",
      "description": "Sandbox (test environment: test documents accepted, Stripe test-mode billing)"
    },
    {
      "url": "https://api.veritypro.ai",
      "description": "Live (production)"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": [],
      "IntegrationId": []
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Your integration API key. S2S only — never send to the browser."
      },
      "IntegrationId": {
        "type": "apiKey",
        "in": "header",
        "name": "Integrationid",
        "description": "UUID of your integration. Optional when authenticating with x-api-key (the key identifies the integration)."
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Short-lived verification-scoped bearer obtained by the browser via `POST /v2/embed/exchange`. Used by the Web SDK for v2 session calls. Never a tenant credential."
      },
      "AccountId": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Account-Id",
        "description": "Transaction Monitoring only: must equal the account your API key belongs to, otherwise 401."
      }
    },
    "schemas": {
      "EmbedMintRequest": {
        "type": "object",
        "required": [
          "firstName",
          "lastName",
          "dateOfBirth",
          "iso2Code",
          "requestedSteps",
          "vendorData",
          "allowedParentOrigin"
        ],
        "properties": {
          "firstName": {
            "type": "string",
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "example": "Doe"
          },
          "dateOfBirth": {
            "type": "string",
            "example": "1990-03-15",
            "description": "Required. Used to create the session at mint time."
          },
          "iso2Code": {
            "type": "string",
            "example": "AU",
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "requestedSteps": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "DOCUMENT",
                "BIOMETRIC",
                "ADDRESS",
                "EDD"
              ]
            },
            "example": [
              "DOCUMENT",
              "BIOMETRIC"
            ],
            "description": "Ordered list of verification steps the user must complete."
          },
          "vendorData": {
            "type": "string",
            "example": "usr_a1b2c3d4",
            "description": "Your internal user / reference ID. Returned in webhooks and session responses."
          },
          "allowedParentOrigin": {
            "type": "string",
            "example": "https://yourapp.com",
            "description": "The exact origin of your web application. postMessage from the verification iframe is restricted to this origin. Must match the registered `VERIFY_ALLOWED_FRAME_ANCESTORS` on the deployment — see deployment prerequisite note above."
          }
        }
      },
      "EmbedMintResponse": {
        "type": "object",
        "properties": {
          "embedToken": {
            "type": "string",
            "example": "evt_Lf7kR2…",
            "description": "One-time token (5 min TTL). Pass to the browser — it will be exchanged for a scoped bearer. Never reuse. The underlying session is created at mint time."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-31T12:05:00Z"
          }
        }
      },
      "EmbedExchangeRequest": {
        "type": "object",
        "required": [
          "embedToken"
        ],
        "properties": {
          "embedToken": {
            "type": "string",
            "description": "The one-time embed token read from the URL fragment."
          }
        }
      },
      "EmbedExchangeResponse": {
        "type": "object",
        "properties": {
          "sessionBearer": {
            "type": "string",
            "description": "Short-lived (15 min) verification-scoped bearer. Held in memory by the SDK only — never persisted to storage."
          },
          "verificationId": {
            "type": "string",
            "format": "uuid",
            "description": "The pre-created v2 session id bound to this token. The SDK fetches this session via GET /v2/sessions/{id} — it does NOT create a new session."
          },
          "allowedParentOrigin": {
            "type": "string",
            "description": "The registered parent origin. The SDK uses this for postMessage targeting (never '*')."
          },
          "expiresInSeconds": {
            "type": "integer",
            "example": 900
          }
        }
      },
      "V2SessionState": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "integrationId": {
            "type": "string",
            "format": "uuid"
          },
          "globalIntegrationId": {
            "type": "string",
            "format": "uuid"
          },
          "vendorData": {
            "type": "string"
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "dateOfBirth": {
            "type": "string",
            "nullable": true
          },
          "ISO2Code": {
            "type": "string",
            "nullable": true
          },
          "requestedSteps": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "completedSteps": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "currentStep": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "example": "Active"
          },
          "kycEngineSessionId": {
            "type": "string",
            "nullable": true
          },
          "kycVerificationId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "addressSessionId": {
            "type": "string",
            "nullable": true
          },
          "addressVerificationId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "eddCaseId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "previousSessionId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "attemptId": {
            "type": "string",
            "nullable": true,
            "description": "Matches kycverification.AttemptId in decision webhooks."
          },
          "initiatedBy": {
            "type": "string",
            "nullable": true
          },
          "billable": {
            "type": "boolean",
            "nullable": true
          },
          "nextAction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NextAction"
              }
            ],
            "nullable": true
          },
          "createdDate": {
            "type": "string",
            "format": "date-time"
          },
          "lastModifiedDate": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateKycRequest": {
        "type": "object",
        "description": "Legacy v1 KYC session request. Use `/v2/embed/mint` + the Web SDK for new integrations.",
        "required": [
          "integrationId",
          "firstName",
          "lastName",
          "ISO2Code"
        ],
        "properties": {
          "integrationId": {
            "type": "string",
            "format": "uuid"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "ISO2Code": {
            "type": "string",
            "example": "AU"
          },
          "dateOfBirth": {
            "type": "string",
            "example": "1990-03-15"
          },
          "requiredModules": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "DOCUMENT",
                "BIOMETRIC",
                "ADDRESS",
                "EDD"
              ]
            }
          }
        }
      },
      "CreateAddressRequest": {
        "type": "object",
        "required": [
          "firstName",
          "lastName",
          "streetAddress",
          "ISO2Code"
        ],
        "properties": {
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "streetAddress": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "stateOrProvince": {
            "type": "string"
          },
          "postalCode": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "vendorData": {
            "type": "string"
          },
          "ISO2Code": {
            "type": "string",
            "example": "AU"
          }
        }
      },
      "EddScreenRequest": {
        "type": "object",
        "required": [
          "subjectId",
          "subjectName"
        ],
        "properties": {
          "subjectId": {
            "type": "string"
          },
          "subjectName": {
            "type": "string"
          },
          "dateOfBirth": {
            "type": "string",
            "example": "1990-03-15"
          },
          "nationality": {
            "type": "string",
            "example": "AU"
          },
          "sourceCountry": {
            "type": "string"
          },
          "destinationCountry": {
            "type": "string"
          },
          "transactionAmount": {
            "type": "number",
            "example": 15000.0
          },
          "transactionCurrency": {
            "type": "string",
            "example": "AUD"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "statusMessage": {
            "type": "string"
          }
        }
      },
      "CreateVerificationSessionRequest": {
        "type": "object",
        "required": [
          "vendorData",
          "steps"
        ],
        "properties": {
          "vendorData": {
            "type": "string",
            "description": "Your customer identifier; returned in every webhook.",
            "example": "your-internal-customer-id"
          },
          "steps": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "DOCUMENT",
                "BIOMETRIC",
                "ADDRESS",
                "EDD",
                "DEFAULT",
                "COMBINED"
              ]
            },
            "example": [
              "DOCUMENT",
              "BIOMETRIC"
            ],
            "description": "DEFAULT = DOCUMENT + BIOMETRIC; COMBINED = all four."
          },
          "previousSessionId": {
            "type": "string",
            "format": "uuid",
            "description": "Link to a prior session (e.g. add ADDRESS later)."
          },
          "firstName": {
            "type": "string",
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "example": "Smith"
          },
          "dateOfBirth": {
            "type": "string",
            "description": "YYYY-MM-DD",
            "example": "1990-01-15"
          },
          "ISO2Code": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2",
            "example": "AU"
          }
        }
      },
      "NextAction": {
        "type": "object",
        "properties": {
          "step": {
            "type": "string",
            "example": "DOCUMENT"
          },
          "type": {
            "type": "string",
            "example": "SDK_CAPTURE"
          },
          "engineSessionId": {
            "type": "string",
            "nullable": true,
            "example": "eng_abc123"
          },
          "sessionUrl": {
            "type": "string",
            "nullable": true,
            "description": "Hosted verification link to send to the customer."
          }
        }
      },
      "V2SessionEnvelope": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer",
            "example": 200
          },
          "statusMessage": {
            "type": "string",
            "example": "Success"
          },
          "data": {
            "$ref": "#/components/schemas/V2SessionState"
          },
          "error": {
            "nullable": true
          }
        }
      },
      "BasicEddTransactionSummary": {
        "type": "object",
        "properties": {
          "declaredMonthlyIncome": {
            "type": "number",
            "nullable": true,
            "example": 5000.0
          },
          "totalAmountSent": {
            "type": "number",
            "nullable": true,
            "example": 12000.0
          },
          "periodDays": {
            "type": "integer",
            "nullable": true,
            "example": 90
          },
          "transactionCount": {
            "type": "integer",
            "nullable": true,
            "example": 12
          }
        }
      },
      "BasicEddTransactionLine": {
        "type": "object",
        "properties": {
          "transactionId": {
            "type": "string",
            "maxLength": 128,
            "nullable": true
          },
          "amount": {
            "type": "number"
          },
          "currency": {
            "type": "string",
            "maxLength": 8,
            "nullable": true
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "CreateBasicEddAssessmentRequest": {
        "type": "object",
        "required": [
          "subjectId",
          "subjectName",
          "transactionSummary"
        ],
        "properties": {
          "subjectId": {
            "type": "string",
            "maxLength": 256,
            "example": "your-user-id"
          },
          "subjectName": {
            "type": "string",
            "maxLength": 512,
            "example": "Jane Smith"
          },
          "employerName": {
            "type": "string",
            "nullable": true,
            "example": "Acme Corp"
          },
          "idempotencyKey": {
            "type": "string",
            "nullable": true,
            "description": "A repeat returns the original assessment.",
            "example": "edd-2026-001"
          },
          "clientReference": {
            "type": "string",
            "nullable": true,
            "example": "REF-001"
          },
          "transactionSummary": {
            "$ref": "#/components/schemas/BasicEddTransactionSummary"
          },
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BasicEddTransactionLine"
            },
            "nullable": true
          },
          "currency": {
            "type": "string",
            "default": "AUD",
            "example": "AUD"
          }
        }
      },
      "BasicEddAssessmentCreated": {
        "type": "object",
        "properties": {
          "assessmentId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "example": "AwaitingDocuments"
          },
          "requiredDocumentTypes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BasicEddFinding": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "severity": {
            "type": "string",
            "example": "LOW"
          },
          "amount": {
            "type": "number",
            "nullable": true
          }
        }
      },
      "FinancialConsistencySummary": {
        "type": "object",
        "properties": {
          "declaredMonthlyIncome": {
            "type": "number",
            "nullable": true
          },
          "verifiedMonthlyIncome": {
            "type": "number",
            "nullable": true
          },
          "totalAmountSent": {
            "type": "number",
            "nullable": true
          },
          "totalCredits": {
            "type": "number",
            "nullable": true
          },
          "totalDebits": {
            "type": "number",
            "nullable": true
          },
          "unexplainedCredits": {
            "type": "number",
            "nullable": true
          },
          "openingBalance": {
            "type": "number",
            "nullable": true
          },
          "closingBalance": {
            "type": "number",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "example": "AUD"
          }
        }
      },
      "BasicEddAssessment": {
        "type": "object",
        "properties": {
          "assessmentId": {
            "type": "string",
            "format": "uuid"
          },
          "subjectId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "example": "Completed"
          },
          "verdict": {
            "type": "string",
            "nullable": true,
            "description": "CONSISTENT | INCONSISTENT | REVIEW_REQUIRED | UNABLE_TO_ASSESS"
          },
          "conclusionSummary": {
            "type": "string",
            "nullable": true
          },
          "reviewRecommended": {
            "type": "boolean"
          },
          "financialSummary": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FinancialConsistencySummary"
              }
            ],
            "nullable": true
          },
          "findings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BasicEddFinding"
            }
          },
          "documentCount": {
            "type": "integer"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "EddError": {
        "type": "object",
        "properties": {
          "error_code": {
            "type": "string",
            "example": "edd_basic_not_entitled"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "CreateStepUpChallengeRequest": {
        "type": "object",
        "required": [
          "subjectId"
        ],
        "properties": {
          "subjectId": {
            "type": "string",
            "maxLength": 500,
            "description": "Must equal the vendorData used at KYC onboarding.",
            "example": "customer-8a3f7b12"
          },
          "riskReason": {
            "type": "string",
            "maxLength": 500,
            "nullable": true,
            "example": "high_value_txn"
          },
          "channelOrigin": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "example": "mobile_android"
          },
          "kycVerificationId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "alertId": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          }
        }
      },
      "StepUpChallenge": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "challengeId": {
            "type": "string"
          },
          "hostedUrl": {
            "type": "string",
            "description": "Send to your customer."
          },
          "stepUpToken": {
            "type": "string"
          },
          "subjectId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "example": "Pending"
          },
          "expiresInSeconds": {
            "type": "integer",
            "example": 300
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "StepUpLivenessSession": {
        "type": "object",
        "properties": {
          "livenessSessionId": {
            "type": "string"
          },
          "region": {
            "type": "string"
          },
          "accessKeyId": {
            "type": "string",
            "nullable": true
          },
          "secretAccessKey": {
            "type": "string",
            "nullable": true
          },
          "sessionToken": {
            "type": "string",
            "nullable": true
          },
          "credentialsExpiration": {
            "type": "string",
            "nullable": true
          }
        },
        "description": "Short-lived, liveness-scoped credentials for streaming the face-liveness check."
      },
      "CompleteStepUpChallengeRequest": {
        "type": "object",
        "required": [
          "livenessSessionId"
        ],
        "properties": {
          "livenessSessionId": {
            "type": "string",
            "maxLength": 200
          },
          "securityAssessmentJson": {
            "type": "string",
            "maxLength": 65536,
            "nullable": true
          },
          "selfieImageB64": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "StepUpChallengeStatus": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "challengeId": {
            "type": "string"
          },
          "subjectId": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "verdict": {
            "type": "string",
            "nullable": true,
            "description": "Passed | Failed | ManualReview"
          },
          "authorized": {
            "type": "boolean"
          },
          "similarityScore": {
            "type": "number",
            "nullable": true
          },
          "livenessVerdict": {
            "type": "boolean",
            "nullable": true
          },
          "livenessConfidence": {
            "type": "number",
            "nullable": true
          },
          "reasonCodes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "attemptCount": {
            "type": "integer"
          },
          "maxAttempts": {
            "type": "integer"
          },
          "lockedUntil": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "decisionId": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "StepUpChallengeEnvelope": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer",
            "example": 200
          },
          "statusMessage": {
            "type": "string",
            "example": "Success"
          },
          "data": {
            "$ref": "#/components/schemas/StepUpChallenge"
          },
          "error": {
            "nullable": true
          }
        }
      },
      "StepUpLivenessSessionEnvelope": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer",
            "example": 200
          },
          "statusMessage": {
            "type": "string",
            "example": "Success"
          },
          "data": {
            "$ref": "#/components/schemas/StepUpLivenessSession"
          },
          "error": {
            "nullable": true
          }
        }
      },
      "StepUpChallengeStatusEnvelope": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer",
            "example": 200
          },
          "statusMessage": {
            "type": "string",
            "example": "Success"
          },
          "data": {
            "$ref": "#/components/schemas/StepUpChallengeStatus"
          },
          "error": {
            "nullable": true
          }
        }
      },
      "TransactionProcessRequest": {
        "type": "object",
        "required": [
          "transaction_id",
          "user_id",
          "transaction_amount",
          "transaction_currency"
        ],
        "properties": {
          "config": {
            "type": "object"
          },
          "transaction_id": {
            "type": "string",
            "example": "TXN-2026-0001"
          },
          "action_type": {
            "type": "string"
          },
          "regulation": {
            "type": "string"
          },
          "user_id": {
            "type": "string",
            "example": "your-user-id"
          },
          "user_fullname": {
            "type": "string"
          },
          "user_firstname": {
            "type": "string",
            "example": "Jane"
          },
          "user_middlename": {
            "type": "string"
          },
          "user_lastname": {
            "type": "string",
            "example": "Smith"
          },
          "user_dob": {
            "type": "string"
          },
          "user_pob": {
            "type": "string"
          },
          "entity_type": {
            "type": "string"
          },
          "nationality": {
            "type": "string"
          },
          "country_of_residence": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "example": "jane@example.com"
          },
          "email_domain": {
            "type": "string"
          },
          "phone_number": {
            "type": "string"
          },
          "ip": {
            "type": "string",
            "example": "203.0.113.10"
          },
          "user_country": {
            "type": "string",
            "example": "AU"
          },
          "user_city": {
            "type": "string"
          },
          "user_region": {
            "type": "string"
          },
          "user_zip": {
            "type": "string"
          },
          "user_street": {
            "type": "string"
          },
          "user_street2": {
            "type": "string"
          },
          "payment_mode": {
            "type": "string",
            "example": "bank_transfer"
          },
          "payment_provider": {
            "type": "string"
          },
          "card_fullname": {
            "type": "string"
          },
          "card_bin": {
            "type": "string"
          },
          "card_hash": {
            "type": "string"
          },
          "card_last": {
            "type": "string"
          },
          "card_expire": {
            "type": "string"
          },
          "avs_result": {
            "type": "string"
          },
          "cvv_result": {
            "type": "string"
          },
          "sca_method": {
            "type": "string"
          },
          "status_3d": {
            "type": "string"
          },
          "funding_source": {
            "type": "string"
          },
          "transaction_amount": {
            "type": "string",
            "example": "500.00",
            "description": "Decimal amount as a string."
          },
          "transaction_currency": {
            "type": "string",
            "example": "AUD"
          },
          "transaction_type": {
            "type": "string",
            "enum": [
              "Payment",
              "Remittance",
              "P2PTransfer",
              "Withdrawal",
              "Deposit",
              "OnlinePayment"
            ],
            "default": "Payment",
            "description": "Name, or the integer 0-5.",
            "example": "Remittance"
          },
          "remittance_purpose": {
            "type": "string"
          },
          "source_of_funds": {
            "type": "string"
          },
          "billing_country": {
            "type": "string"
          },
          "billing_city": {
            "type": "string"
          },
          "billing_region": {
            "type": "string"
          },
          "billing_zip": {
            "type": "string"
          },
          "billing_street": {
            "type": "string"
          },
          "billing_street2": {
            "type": "string"
          },
          "receiver_fullname": {
            "type": "string",
            "example": "John Doe"
          },
          "receiver_firstname": {
            "type": "string"
          },
          "receiver_middlename": {
            "type": "string"
          },
          "receiver_lastname": {
            "type": "string"
          },
          "receiver_id": {
            "type": "string"
          },
          "receiver_dob": {
            "type": "string"
          },
          "receiver_pob": {
            "type": "string"
          },
          "receiver_country": {
            "type": "string",
            "example": "US"
          },
          "receiver_photoid_number": {
            "type": "string"
          },
          "receiver_bank_account": {
            "type": "string"
          },
          "receiver_bank_name": {
            "type": "string"
          },
          "receiver_bank_swift": {
            "type": "string"
          },
          "receiver_bank_country": {
            "type": "string"
          },
          "receiving_amount": {
            "type": "string"
          },
          "receiving_currency": {
            "type": "string"
          },
          "exchange_rate": {
            "type": "string"
          },
          "payout_method": {
            "type": "string"
          },
          "relationship_to_beneficiary": {
            "type": "string"
          },
          "affiliate_id": {
            "type": "string"
          },
          "affiliate_name": {
            "type": "string"
          },
          "merchant_id": {
            "type": "string"
          },
          "merchant_name": {
            "type": "string"
          },
          "merchant_category": {
            "type": "string"
          },
          "merchant_country": {
            "type": "string"
          },
          "merchant_url": {
            "type": "string"
          },
          "shipping_fullname": {
            "type": "string"
          },
          "shipping_country": {
            "type": "string"
          },
          "shipping_city": {
            "type": "string"
          },
          "shipping_region": {
            "type": "string"
          },
          "shipping_zip": {
            "type": "string"
          },
          "shipping_street": {
            "type": "string"
          },
          "shipping_phone": {
            "type": "string"
          },
          "shipping_method": {
            "type": "string"
          },
          "originator_national_id": {
            "type": "string"
          },
          "user_photoid_number": {
            "type": "string"
          },
          "originator_date_of_birth": {
            "type": "string"
          },
          "originator_place_of_birth": {
            "type": "string"
          },
          "originator_customer_ref": {
            "type": "string"
          },
          "document_type": {
            "type": "string"
          },
          "sender_account": {
            "type": "string"
          },
          "beneficiary_name": {
            "type": "string"
          },
          "password_hash": {
            "type": "string"
          },
          "user_bank_name": {
            "type": "string"
          },
          "user_bank_account": {
            "type": "string"
          },
          "user_bank_swift": {
            "type": "string"
          },
          "user_bank_country": {
            "type": "string"
          },
          "user_balance": {
            "type": "string"
          },
          "user_category": {
            "type": "string"
          },
          "user_account_status": {
            "type": "string"
          },
          "user_verification_level": {
            "type": "string"
          },
          "user_created": {
            "type": "integer",
            "format": "int64"
          },
          "pos_lat": {
            "type": "number"
          },
          "pos_long": {
            "type": "number"
          },
          "session": {
            "type": "string",
            "description": "Device session token (vpds_...) from the Device SDK."
          },
          "vertical": {
            "type": "string"
          },
          "vertical_data": {
            "type": "object"
          },
          "wallet_address": {
            "type": "string"
          },
          "blockchain_network": {
            "type": "string"
          },
          "original_transaction_id": {
            "type": "string"
          },
          "chargeback_count": {
            "type": "integer"
          },
          "refund_amount": {
            "type": "string"
          },
          "is_refund": {
            "type": "boolean"
          },
          "custom_fields": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        },
        "description": "snake_case. Amounts are strings. Request size limit 64 KB."
      },
      "AppliedRule": {
        "type": "object",
        "properties": {
          "Id": {
            "type": "string"
          },
          "Name": {
            "type": "string"
          },
          "Category": {
            "type": "string",
            "nullable": true
          },
          "Score": {
            "type": "number"
          }
        }
      },
      "TransactionDecision": {
        "type": "object",
        "properties": {
          "Id": {
            "type": "string",
            "example": "TXN-2026-0001"
          },
          "State": {
            "type": "string",
            "enum": [
              "APPROVE",
              "REVIEW",
              "CHALLENGE",
              "BLOCK"
            ],
            "example": "APPROVE"
          },
          "FraudScore": {
            "type": "number",
            "example": 0.04
          },
          "RiskLevel": {
            "type": "string",
            "example": "LOW"
          },
          "IntelligenceComplete": {
            "type": "boolean"
          },
          "RulesEvaluated": {
            "type": "integer"
          },
          "RulesTriggered": {
            "type": "integer"
          },
          "AppliedRules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AppliedRule"
            }
          },
          "RiskIndicators": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ProcessingTimeMs": {
            "type": "integer"
          },
          "ProcessedAt": {
            "type": "string",
            "format": "date-time"
          },
          "DetailsUrl": {
            "type": "string"
          },
          "TestMode": {
            "type": "boolean"
          },
          "ScreeningDegraded": {
            "type": "boolean",
            "description": "True: a screening stage did not run; hold funds."
          },
          "DegradedStages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "HoldReasons": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "SANCTIONS_UNAVAILABLE",
                "SCREENING_DEGRADED",
                "PROCESSING_ERROR"
              ]
            }
          }
        },
        "description": "PascalCase property names (this service serialises with Newtonsoft default naming)."
      },
      "DeviceSignals": {
        "type": "object",
        "properties": {
          "canvas_hash": {
            "type": "string"
          },
          "webgl_hash": {
            "type": "string"
          },
          "audio_hash": {
            "type": "string"
          },
          "screen": {
            "type": "object"
          },
          "tz_offset": {
            "type": "integer"
          },
          "tz_name": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "ua": {
            "type": "string"
          },
          "platform": {
            "type": "string",
            "example": "web"
          },
          "hw_concurrency": {
            "type": "integer"
          },
          "device_memory": {
            "type": "number"
          },
          "touch_points": {
            "type": "integer"
          },
          "connection": {
            "type": "string"
          }
        },
        "description": "At least one signal is required. Normally collected by the Device SDK."
      },
      "DeviceSessionRequest": {
        "type": "object",
        "required": [
          "integration_id",
          "signals"
        ],
        "properties": {
          "integration_id": {
            "type": "string",
            "format": "uuid",
            "example": "YOUR_INTEGRATION_UUID"
          },
          "sdk_version": {
            "type": "string"
          },
          "page_origin": {
            "type": "string"
          },
          "signals": {
            "$ref": "#/components/schemas/DeviceSignals"
          }
        }
      },
      "DeviceSessionResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "example": "vpds_..."
          },
          "expires_in": {
            "type": "integer",
            "example": 3600
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Hosted Verification (v2)",
      "description": "Recommended integration path. Your backend mints an embed token (S2S), passes it to the Web SDK, and confirms the result via GET session (S2S) or webhook."
    },
    {
      "name": "KYC Verification",
      "description": "Document, liveness, and identity verification."
    },
    {
      "name": "Address Verification",
      "description": "Proof-of-address document verification."
    },
    {
      "name": "Enhanced Due Diligence",
      "description": "EDD screening — PEP, sanctions, source of funds."
    },
    {
      "name": "AML Transaction Monitoring",
      "description": "Real-time AML risk scoring for transactions."
    },
    {
      "name": "Step-Up Authentication"
    },
    {
      "name": "Device Intelligence"
    }
  ],
  "paths": {
    "/kycintegration/v2/embed/mint": {
      "post": {
        "summary": "Mint an embed token (S2S)",
        "tags": [
          "Hosted Verification (v2)"
        ],
        "description": "Create a one-time embed token that authorises a single user to complete a verification session. **Call this from your backend only** — your API key must never reach the browser.\n\nThe backend creates the verification session at mint time using the supplied identity details and step configuration. The token binds that pre-created session so no separate session-creation call is required from the browser.\n\nToken TTL: 5 minutes. Single-use — replay is rejected.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmbedMintRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token minted. Pass `embedToken` to the Web SDK's `mount({ embedToken })` call.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmbedMintResponse"
                },
                "example": {
                  "embedToken": "evt_Lf7kR2mN9pQx…",
                  "expiresAt": "2026-08-31T12:05:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "API key / integration id mismatch."
          }
        }
      }
    },
    "/kycintegration/v2/embed/exchange": {
      "post": {
        "summary": "Exchange embed token for a session bearer (browser)",
        "tags": [
          "Hosted Verification (v2)"
        ],
        "description": "Called automatically by the VerityPro Web SDK. The browser reads the embed token from the URL fragment (never query string) and exchanges it for a short-lived, verification-scoped bearer that lives only in a JS module closure — never `localStorage` or `sessionStorage`.\n\nThe response includes `verificationId`, which is the id of the **pre-created** session from mint time. The SDK fetches that session via `GET /v2/sessions/{id}`; it does not create a new session. Do not call this endpoint from your backend.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmbedExchangeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bearer issued. The SDK uses `verificationId` to fetch the pre-created session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmbedExchangeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Token missing, malformed, or already used."
          },
          "410": {
            "description": "Token expired (TTL elapsed)."
          }
        }
      }
    },
    "/kycintegration/v2/sessions": {
      "post": {
        "summary": "Create a verification session (S2S)",
        "tags": [
          "Hosted Verification (v2)"
        ],
        "description": "Creates a v2 session. Send `data.nextAction.sessionUrl` to your customer, or drive capture with an SDK.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVerificationSessionRequest"
              },
              "example": {
                "vendorData": "your-internal-customer-id",
                "steps": [
                  "DOCUMENT",
                  "BIOMETRIC"
                ],
                "firstName": "Jane",
                "lastName": "Smith",
                "dateOfBirth": "1990-01-15",
                "ISO2Code": "AU"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V2SessionEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "API key missing or invalid."
          }
        }
      }
    },
    "/kycintegration/v2/sessions/{id}": {
      "get": {
        "summary": "Get session state (S2S)",
        "tags": [
          "Hosted Verification (v2)"
        ],
        "description": "Retrieve the current state of a v2 session.\n\n**Current production:** requires `x-api-key` + `Integrationid` (S2S only). Call this from your backend to confirm the authoritative result after the SDK fires `onResult`, or after receiving a webhook. **Never rely solely on the browser-side `onResult` to gate access.**\n\n**Target (pending bearer deployment):** the SDK also calls this endpoint with the session-scoped bearer after token exchange to fetch the pre-created session and derive which steps to render. This bearer-acceptance path is implemented in the hosted SDK but not yet enforced by the backend in production.",
        "security": [
          {
            "ApiKeyAuth": [],
            "IntegrationId": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The v2 session id (from `verificationId` in the exchange response, or from the webhook)."
          }
        ],
        "responses": {
          "200": {
            "description": "Session found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V2SessionEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "API key missing or invalid."
          },
          "404": {
            "description": "Session not found."
          }
        }
      }
    },
    "/kycintegration/v2/sessions/{id}/steps/{step}/complete": {
      "post": {
        "summary": "Mark a step complete (hosted SDK internal)",
        "tags": [
          "Hosted Verification (v2)"
        ],
        "description": "Advance the session to the next step after all uploads for the current step are processed. Called automatically by the hosted SDK after document submission and OCR processing (retried while status is `processing`). You only need this if building a fully custom capture integration.\n\nAuth: session-scoped bearer (target) / API key (current production).",
        "security": [
          {
            "ApiKeyAuth": [],
            "IntegrationId": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The v2 session id."
          },
          {
            "name": "step",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "DOCUMENT",
                "BIOMETRIC",
                "ADDRESS",
                "EDD"
              ]
            },
            "description": "The step to mark complete."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Step marked complete. Check `data.currentStep` for the next step or `data.status` for terminal state.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/V2SessionState"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Step is still processing (e.g. OCR in progress). Retry after a short delay."
          },
          "401": {
            "description": "Auth missing or expired."
          },
          "409": {
            "description": "Step already completed."
          }
        }
      }
    },
    "/kycintegration/kyc-verification/update-kyc-verification": {
      "post": {
        "summary": "Submit captured ID document images (DOCUMENT step)",
        "tags": [
          "KYC Verification"
        ],
        "description": "Submit captured ID document images for the DOCUMENT step. Keyed by `kycEngineSessionId` (from `GET /v2/sessions/{id}` → `data.kycEngineSessionId`) — **not** the v2 session UUID.\n\nCalled automatically by the Web SDK. You only need this if you are building a custom capture UI.\n\nAuth: bearer token (from exchange) in `Authorization` header.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "SessionId",
                  "DocumentType"
                ],
                "properties": {
                  "SessionId": {
                    "type": "string",
                    "description": "`kycEngineSessionId` from the session state — NOT the v2 UUID."
                  },
                  "DocumentType": {
                    "type": "integer",
                    "description": "Document type: Passport=1, DriverLicence=2, NationalId=3.",
                    "enum": [
                      1,
                      2,
                      3
                    ]
                  },
                  "DocumentFront": {
                    "type": "string",
                    "format": "binary"
                  },
                  "DocumentBack": {
                    "type": "string",
                    "format": "binary",
                    "description": "Required for two-sided documents (e.g. driver licence)."
                  },
                  "PortraitPicture": {
                    "type": "string",
                    "format": "binary",
                    "description": "Selfie portrait (when not using separate liveness)."
                  },
                  "PlatformUsed": {
                    "type": "string",
                    "example": "web"
                  },
                  "SecurityAssessmentJson": {
                    "type": "string",
                    "description": "JSON-encoded device/capture security signals matching mobile SDK format."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Documents accepted and queued for processing."
          },
          "400": {
            "description": "Missing or invalid fields."
          },
          "401": {
            "description": "Bearer missing or expired."
          }
        }
      }
    },
    "/kycintegration/kyc-verification/add-kyc-verification": {
      "post": {
        "summary": "Create a KYC session (legacy v1)",
        "tags": [
          "KYC Verification"
        ],
        "description": "**Legacy.** Creates a session and returns a hosted `sessionUrl` for the old `/verify/[id]` flow. Use `/v2/embed/mint` + the Web SDK for new integrations — better security, richer UI, and mobile parity.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateKycRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session created. Response contains a hosted `sessionUrl` pointing to the legacy `/verify/[id]` flow."
          },
          "403": {
            "description": "Integrationid does not match the key."
          }
        }
      }
    },
    "/addressverification/address-verification/add-verification": {
      "post": {
        "summary": "Create an address verification (S2S or hosted flow)",
        "tags": [
          "Address Verification"
        ],
        "description": "Create an address verification session. In the hosted embed flow, address document capture is orchestrated inside the `/hosted-verify` page and does not require a direct call to this endpoint from the browser — it is submitted internally by the hosted client. Use this endpoint from your backend for server-initiated address verification.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAddressRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Address verification created."
          }
        }
      }
    },
    "/edd/api/v1/edd/basic/screen": {
      "post": {
        "summary": "Basic EDD screen (S2S)",
        "tags": [
          "Enhanced Due Diligence"
        ],
        "description": "Run a basic EDD screen (PEP, sanctions, adverse media) from your backend. Returns 200 for a clean result, 202 when a full EDD investigation is required.\n\nIn the hosted embed flow, EDD document collection is orchestrated inside the `/hosted-verify` page — a direct call to this endpoint from the browser is not required for the embed flow.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EddScreenRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Screen completed — subject is clean."
          },
          "202": {
            "description": "Full EDD investigation required."
          }
        }
      }
    },
    "/kycintegration/kyc-verification/trigger-edd": {
      "post": {
        "summary": "Trigger EDD for a verified customer",
        "tags": [
          "Enhanced Due Diligence"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vendorData",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "your-internal-customer-id"
            },
            "description": "The vendorData used at KYC onboarding."
          }
        ],
        "responses": {
          "200": {
            "description": "EDD triggered.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "statusMessage": {
                      "type": "string"
                    },
                    "data": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "vendorData missing."
          },
          "401": {
            "description": "API key missing or invalid."
          },
          "404": {
            "description": "No verification found for this vendorData."
          }
        }
      }
    },
    "/edd/api/v1/edd/basic/assessments": {
      "post": {
        "summary": "Create a Basic EDD assessment",
        "tags": [
          "Enhanced Due Diligence"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBasicEddAssessmentRequest"
              },
              "example": {
                "subjectId": "your-user-id",
                "subjectName": "Jane Smith",
                "employerName": "Acme Corp",
                "idempotencyKey": "edd-2026-001",
                "clientReference": "REF-001",
                "transactionSummary": {
                  "declaredMonthlyIncome": 5000.0,
                  "totalAmountSent": 12000.0,
                  "periodDays": 90,
                  "transactionCount": 12
                },
                "currency": "AUD"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created; awaiting documents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BasicEddAssessmentCreated"
                }
              }
            }
          },
          "401": {
            "description": "API key missing or invalid."
          },
          "403": {
            "description": "Integration not entitled to Basic EDD (or plan does not include it).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EddError"
                }
              }
            }
          }
        }
      }
    },
    "/edd/api/v1/edd/basic/assessments/{assessmentId}/documents": {
      "post": {
        "summary": "Attach a supporting document",
        "tags": [
          "Enhanced Due Diligence"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "assessmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "document"
                ],
                "properties": {
                  "document": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Document attached.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BasicEddAssessment"
                }
              }
            }
          },
          "400": {
            "description": "A document file is required."
          },
          "401": {
            "description": "API key missing or invalid."
          },
          "403": {
            "description": "Integration not entitled to Basic EDD (or plan does not include it).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EddError"
                }
              }
            }
          }
        }
      }
    },
    "/edd/api/v1/edd/basic/assessments/{assessmentId}/submit": {
      "post": {
        "summary": "Submit the assessment for processing",
        "tags": [
          "Enhanced Due Diligence"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "assessmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted for processing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BasicEddAssessment"
                }
              }
            }
          },
          "401": {
            "description": "API key missing or invalid."
          },
          "403": {
            "description": "Integration not entitled to Basic EDD (or plan does not include it).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EddError"
                }
              }
            }
          }
        }
      }
    },
    "/edd/api/v1/edd/basic/assessments/{assessmentId}": {
      "get": {
        "summary": "Get assessment status and verdict",
        "tags": [
          "Enhanced Due Diligence"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "assessmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Assessment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BasicEddAssessment"
                }
              }
            }
          },
          "401": {
            "description": "API key missing or invalid."
          },
          "403": {
            "description": "Integration not entitled to Basic EDD (or plan does not include it).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EddError"
                }
              }
            }
          }
        }
      }
    },
    "/kycintegration/api/v1/step-up/challenges": {
      "post": {
        "summary": "Create a step-up challenge",
        "tags": [
          "Step-Up Authentication"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "x-api-key only. The subject must have completed a liveness-verified KYC session.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateStepUpChallengeRequest"
              },
              "example": {
                "subjectId": "customer-8a3f7b12",
                "riskReason": "high_value_txn",
                "channelOrigin": "mobile_android"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Challenge created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StepUpChallengeEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed."
          },
          "401": {
            "description": "API key missing or invalid."
          },
          "422": {
            "description": "Subject not eligible (no liveness-verified KYC)."
          }
        }
      }
    },
    "/kycintegration/api/v1/step-up/challenges/{challengeId}/begin-liveness": {
      "post": {
        "summary": "Begin the liveness check (native integration)",
        "tags": [
          "Step-Up Authentication"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "challengeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liveness session bound to the challenge.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StepUpLivenessSessionEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "API key missing or invalid."
          },
          "404": {
            "description": "Challenge not found."
          },
          "410": {
            "description": "Challenge expired."
          }
        }
      }
    },
    "/kycintegration/api/v1/step-up/challenges/{challengeId}/complete": {
      "post": {
        "summary": "Complete the challenge",
        "tags": [
          "Step-Up Authentication"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "challengeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteStepUpChallengeRequest"
              },
              "example": {
                "livenessSessionId": "LIVENESS_SESSION_ID"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verdict.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StepUpChallengeStatusEnvelope"
                }
              }
            }
          },
          "401": {
            "description": "API key missing or invalid."
          },
          "404": {
            "description": "Challenge not found."
          },
          "410": {
            "description": "Challenge expired."
          },
          "429": {
            "description": "Too many attempts."
          }
        }
      }
    },
    "/transactionprocessing/api/v1/transactions/process": {
      "post": {
        "summary": "Process a transaction (AML risk decision)",
        "tags": [
          "AML Transaction Monitoring"
        ],
        "description": "Requires the Transaction Monitoring capability. `X-Account-Id` must equal the account the API key belongs to.",
        "security": [
          {
            "ApiKeyAuth": [],
            "AccountId": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionProcessRequest"
              },
              "example": {
                "transaction_id": "TXN-2026-0001",
                "user_id": "your-user-id",
                "transaction_amount": "500.00",
                "transaction_currency": "AUD",
                "transaction_type": "Remittance",
                "user_firstname": "Jane",
                "user_lastname": "Smith",
                "email": "jane@example.com",
                "user_country": "AU",
                "ip": "203.0.113.10",
                "receiver_fullname": "John Doe",
                "receiver_country": "US",
                "payment_mode": "bank_transfer"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Decision.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionDecision"
                }
              }
            }
          },
          "401": {
            "description": "API key missing/invalid, or X-Account-Id does not match the key's account."
          },
          "403": {
            "description": "Missing permission or the Transaction Monitoring capability."
          },
          "422": {
            "description": "Validation failed: [{field, errorCode}]."
          },
          "503": {
            "description": "No decision was made (transaction could not be persisted); retry."
          }
        }
      }
    },
    "/aml-intelligence/api/v1/device/sessions": {
      "post": {
        "summary": "Create a device session",
        "tags": [
          "Device Intelligence"
        ],
        "description": "Anonymous (called from the browser by the Device SDK); attribution is by integration_id. Pass the returned token as `session` when you submit the transaction.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceSessionRequest"
              },
              "example": {
                "integration_id": "YOUR_INTEGRATION_UUID",
                "signals": {
                  "platform": "web"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token issued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceSessionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid integration_id, stale or empty signals."
          },
          "503": {
            "description": "Signals could not be stored; retry."
          }
        }
      }
    }
  }
}
