{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/signdocs-com-br/json-schema/signdocs-com-br-advance-session-response-schema.json",
  "title": "AdvanceSessionResponse",
  "description": "Resposta do avanço da sessão.",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/signdocs-com-br-openapi.yaml#/components/schemas/AdvanceSessionResponse",
  "type": "object",
  "required": [
    "sessionId",
    "status"
  ],
  "properties": {
    "sessionId": {
      "type": "string"
    },
    "status": {
      "$ref": "#/$defs/SigningSessionStatus"
    },
    "currentStep": {
      "type": "object",
      "description": "Etapa atual sendo processada.",
      "properties": {
        "stepId": {
          "type": "string"
        },
        "type": {
          "type": "string"
        },
        "status": {
          "type": "string"
        }
      }
    },
    "nextStep": {
      "type": "object",
      "description": "Próxima etapa pendente (se houver).",
      "properties": {
        "stepId": {
          "type": "string"
        },
        "type": {
          "type": "string"
        }
      }
    },
    "evidenceId": {
      "type": "string",
      "description": "ID da evidência (presente quando status é COMPLETED)."
    },
    "redirectUrl": {
      "type": "string",
      "format": "uri",
      "description": "URL de redirecionamento (returnUrl + session_id)."
    },
    "completedAt": {
      "type": "string",
      "format": "date-time",
      "description": "Data/hora de conclusão (quando status é COMPLETED)."
    },
    "hostedUrl": {
      "type": "string",
      "format": "uri",
      "description": "URL da página de liveness hospedada (para `start_liveness`)."
    },
    "livenessSessionId": {
      "type": "string",
      "description": "ID da sessão Rekognition (para `start_liveness`)."
    },
    "signatureRequestId": {
      "type": "string",
      "description": "ID da requisição de assinatura (para `prepare_signing`)."
    },
    "hashToSign": {
      "type": "string",
      "description": "Hash a ser assinado pelo certificado (para `prepare_signing`)."
    },
    "hashAlgorithm": {
      "type": "string",
      "description": "Algoritmo do hash (ex. SHA-256)."
    },
    "signatureAlgorithm": {
      "type": "string",
      "description": "Algoritmo de assinatura esperado (ex. SHA256withRSA)."
    },
    "sandbox": {
      "type": "object",
      "description": "Dados de sandbox (apenas em HML). Contém o OTP para testes.",
      "properties": {
        "otpCode": {
          "type": "string"
        },
        "autoPass": {
          "type": "boolean",
          "description": "Indica que a etapa biométrica será aprovada automaticamente."
        }
      }
    },
    "errorCode": {
      "type": "string",
      "description": "Motivo da reprovação de uma etapa, quando ela falha **sem** que a\nrequisição falhe. Esta é a parte que mais importa numa integração\nbiométrica: uma etapa reprovada volta **200** com a sessão ainda\n`ACTIVE` e o motivo aqui — não como erro HTTP. Quem trata só o\nstatus HTTP lê uma reprovação como sucesso.\n\nValores emitidos hoje:\n\n| Código | Significado |\n|---|---|\n| `BIOMETRIC_MATCH_FAILED` | Similaridade abaixo do limiar exigido |\n| `LIVENESS_NOT_COMPLETED` | A captura de vivacidade não foi concluída |\n| `DOCUMENT_QUALITY_LOW` | Brilho ou nitidez abaixo do piso do tenant |\n| `DOCUMENT_MATCH_FAILED` | A comparação com a foto do documento não foi aprovada |\n| `SERPRO_*` | Falha na consulta SERPRO — `SERPRO_TIMEOUT`, `SERPRO_RATE_LIMITED`, `SERPRO_CIRCUIT_OPEN`, `SERPRO_AUTH_FAILURE`, `SERPRO_CREDENTIALS_ERROR`, `SERPRO_INVALID_REQUEST`, `SERPRO_SERVER_ERROR` |\n\n`CPF_REQUIRED` e `CPF_MISMATCH` não aparecem aqui: são 400, com o\ncódigo dentro do corpo do problema, não desta resposta 200.\n"
    },
    "errorDetail": {
      "type": "string",
      "description": "Texto em pt-BR destinado ao signatário, pronto para ser exibido.\nDescreve o que fazer, não o que houve internamente.\n"
    },
    "retryable": {
      "type": "boolean",
      "description": "`true` enquanto restam tentativas na etapa. Quando as tentativas\nacabam a etapa vai a `FAILED` e este campo vem `false` — é o sinal\nde que insistir não adianta. Cada nova tentativa é cobrada como\nexcedente.\n"
    },
    "fallback": {
      "type": "object",
      "description": "Presente quando a política desviou para uma etapa alternativa em vez\nde reprovar de vez — por exemplo, biometria que cai para comparação\ncom foto do documento.\n",
      "properties": {
        "triggered": {
          "type": "boolean"
        },
        "reason": {
          "type": "string"
        },
        "nextStepType": {
          "type": "string"
        }
      }
    }
  },
  "$defs": {
    "SigningSessionStatus": {
      "type": "string",
      "description": "Status da sessão de assinatura.",
      "enum": [
        "ACTIVE",
        "COMPLETED",
        "CANCELLED",
        "EXPIRED",
        "FAILED"
      ]
    }
  }
}