Começar
Introdução
A MoDI Open API (versão 1.3) permite a instituições integrar serviços de identidade digital: leitura de documentos (OCR), comparação facial, prova de vida, sessões de verificação KYC completas, envio de SMS e verificação de números móveis junto das operadoras (Subscriber Check).
Todas as respostas, incluindo erros, seguem o mesmo envelope JSON. As operações estão organizadas por serviço e cada uma exige a chave da respectiva subscrição.
Os dados de todas as requisições, incluindo os testes online, são armazenados permanentemente na base de dados do MoDI.
Perfis
| Perfil | Acesso |
|---|---|
| INSTITUTION | Catálogo, subscrição e activação de serviços e todos os endpoints operacionais. É o perfil documentado nesta página. |
| ADMIN_BACKOFFICE | Equipa MoDI: revê, aprova e rejeita manifestações de interesse. Sem acesso aos serviços operacionais. |
Início rápido
O percurso de integração tem sete passos:
| Passo | Acção | Operação |
|---|---|---|
| 1 | Submeter manifestação de interesse | POST /institutions/interest |
| 2 | Obter aprovação (credenciais enviadas por e-mail) | GET /institutions/interest/{requestId} |
| 3 | Iniciar sessão | POST /auth/login |
| 4 | Alterar a senha temporária | POST /auth/password |
| 5 | Subscrever um serviço | POST /services/subscriptions |
| 6 | Activar a chave de Sandbox | POST /services/subscriptions/{subscriptionId}/activate |
| 7 | Consumir o serviço | Endpoint operacional com X-API-Key |
Manifestação de interesse
→ Aprovação
→ Login
→ Alterar senha temporária
→ Subscrever serviço
→ Activar chave SANDBOX
→ Consumir o serviçoAmbientes
| Ambiente | URL base | Finalidade |
|---|---|---|
| Sandbox | https://sandbox.openapikyc.co.mz/v1 | Testes, sem custo |
| Produção | https://api.openapikyc.co.mz/v1 | Tráfego real, facturável |
Regras
As chaves são activadas separadamente por ambiente: uma subscrição pode ter uma chave SANDBOX e uma chave PRODUCTION.
A activação em SANDBOX gera automaticamente o MOU informativo associado. PRODUCTION requer homologação prévia.
Pendente no contrato: O procedimento de homologação para produção não está descrito no contrato.
Pendente: O procedimento de homologação para produção não está descrito no contrato.
Iniciar sessão
POST/auth/login
Autenticação por e-mail e password. Devolve o accessToken a usar no header Authorization.
Requisitos
- Sem autenticação
- Content-Type: application/json ou multipart/form-data
Corpo (application/json)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| string | Obrigatório | — | |
| password | string | Obrigatório | — |
Regras
role e mustChangePassword vêm codificados como claims dentro do accessToken (JWT), não no corpo da resposta.
Enquanto mustChangePassword for true, apenas POST /auth/password fica acessível; os restantes endpoints devolvem 403 PASSWORD_CHANGE_REQUIRED.
curl -X POST "https://sandbox.openapikyc.co.mz/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"compliance@exemplo.co.mz","password":"<password>"}'Alterar password
POST/auth/password
Obrigatório no primeiro login com password temporária. A password temporária é de uso único.
Requisitos
- Authorization: Bearer <accessToken>
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
Corpo (application/json)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| currentPassword | string | Obrigatório | Password actual ou temporária |
| newPassword | string | Obrigatório | Requisitos internacionais de complexidade |
Regras
mustChangePassword fica true até o primeiro POST /auth/password ser concluído.
curl -X POST "https://sandbox.openapikyc.co.mz/v1/auth/password" \
-H "Authorization: Bearer <accessToken>" \
-H "Content-Type: application/json" \
-d '{"currentPassword":"<temporária>","newPassword":"<nova>"}'Headers
| Header | Uso |
|---|---|
| Authorization | Bearer <accessToken>. Obrigatório em todas as chamadas protegidas. |
| X-API-Key | Chave da subscrição do serviço. Obrigatória nos endpoints operacionais. |
| Content-Type | application/json ou multipart/form-data (envio de ficheiros). |
| Idempotency-Key | UUID por pedido. Recomendado em POSTs facturáveis. |
| X-Request-Id | Identificador de rastreio devolvido em todas as respostas. |
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11"Formato das respostas
Todas as respostas seguem o mesmo envelope, incluindo os erros.
| Campo | Tipo | Significado |
|---|---|---|
| success | boolean | Sucesso técnico do pedido. |
| status | number | Código HTTP da resposta. |
| message | string | Mensagem descritiva. |
| data | object | null | Resultado da operação; null em caso de erro. |
| transactionId | string | Identificador da transacção. |
| amount | string | Valor associado à transacção. |
| errors | array | null | Lista de erros; null em caso de sucesso. |
Regras
success indica que o pedido foi processado; não indica o resultado da verificação. Esse resultado está em data (por exemplo data.result ou data.passed).
Os valores de amount nos exemplos são ilustrativos e não representam preços comerciais.
{
"success": true,
"status": 200,
"message": "Operation completed successfully.",
"data": {},
"transactionId": "TRX-EXEMPLO",
"amount": "0.00",
"errors": null
}Tratamento de erros
Em erro: success: false, data: null e errors preenchido com code, field e detail.
Distinguir resultados
| Situação | Como se identifica |
|---|---|
| Sucesso técnico | success: true, HTTP 2xx |
| Resultado da verificação | HTTP 200 com data.result / data.passed (pode ser negativo) |
| Erro de validação | HTTP 400 ou 422, errors com o campo |
| Falha de autenticação | HTTP 401 (token) ou 403 (scope, serviço, password) |
| Indisponibilidade | HTTP 503; a sessão permanece em PROCESSING |
Códigos HTTP
| HTTP | Quando ocorre |
|---|---|
| 400 | Requisição malformada |
| 401 | Token ausente, inválido ou expirado |
| 402 | Saldo insuficiente (INSUFFICIENT_BALANCE) |
| 403 | Scope insuficiente ou serviço não contratado |
| 404 | Recurso inexistente |
| 409 | Conflito de idempotência |
| 422 | Falha de validação de negócio |
| 429 | Rate limit excedido (Retry-After) |
| 500 | Erro interno; repetir com a mesma Idempotency-Key |
| 503 | Provedor externo indisponível; sessão permanece em PROCESSING |
Códigos de negócio
| Código | Descrição |
|---|---|
| INVALID_FILE_FORMAT | Ficheiro fora dos formatos aceites (JPG, JPEG, PNG, PDF) |
| FILE_TOO_LARGE | Ficheiro excede 5 MB |
| DOCUMENT_UNREADABLE | Qualidade insuficiente para OCR |
| DOCUMENT_EXPIRED | Documento com validade ultrapassada |
| FACE_NOT_DETECTED | Nenhuma face detectada na selfie |
| FACE_MISMATCH | Similaridade abaixo do limiar contratado |
| LIVENESS_FAILED | Prova de vida detectou possível fraude |
| DUPLICATE_IDENTITY_FOUND | A face corresponde a uma identidade já existente |
| UNDERAGE_APPLICANT | Proponente abaixo da idade mínima configurada |
| PHONE_INVALID | Número de telefone inválido ou não E.164 |
| SESSION_EXPIRED | Sessão de verificação expirada |
| INSUFFICIENT_BALANCE | Saldo pré-pago insuficiente para a operação |
| SERVICE_NOT_ENABLED | Serviço não incluído no plano contratado |
| PASSWORD_CHANGE_REQUIRED | Password temporária ainda não foi alterada |
| SUBSCRIBER_DATA_REQUIRED | Contact-verify sem nome, n.º do documento ou data de nascimento válidos (422) |
| SELFIE_REQUIRED | Bio-verify sem selfie (422) |
| DOCUMENT_REQUIRED | Bio-verify sem frente do documento (422) |
| SUBSCRIBER_NOT_FOUND | Número sem registo na operadora (422) |
| SUBSCRIBER_BIOMETRY_NOT_FOUND | Titular sem fotografia de registo na operadora (422) |
| SUBSCRIBER_INVALID_DATA | Dados recusados pela operadora; detalhe por campo em errors (400/413) |
| SUBSCRIBER_LEVEL_NOT_ALLOWED | A operadora não tem acordo para o nível pedido nem para um nível abaixo (403) |
| SUBSCRIBER_RATE_LIMITED | Limite de pedidos da operadora excedido (429) |
| SUBSCRIBER_CHECK_UNAVAILABLE | Serviço da operadora indisponível ou sem configuração (503) |
{
"success": false,
"status": 422,
"message": "Validation failed.",
"data": null,
"transactionId": "TRX-20260709-000160",
"amount": "0.00",
"errors": [
{
"code": "DOCUMENT_EXPIRED",
"field": "documentFront",
"detail": "O documento apresentado expirou."
}
]
}Acesso e configuração
Submeter manifestação de interesse
POST/institutions/interest
Cria o registo com estado PENDING na fila de revisão da MoDI. Após aprovação, a instituição recebe por e-mail as credenciais; em caso de rejeição, recebe o motivo.
Requisitos
- Sem autenticação
- multipart/form-data
Corpo (multipart/form-data)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| companyName | string | Obrigatório | Nome legal da instituição |
| address | string | Obrigatório | — |
| string | Obrigatório | Torna-se o login da instituição, após aprovação | |
| phoneNumber | string | Obrigatório | Formato E.164 |
| websiteUrl | string | Opcional | — |
| taxId | file | Obrigatório | NUIT (documento anexo) |
| licenseDocument | file | Obrigatório | Alvará |
| commercialCertificate | file | Obrigatório | Certidão Comercial |
curl -X POST "https://sandbox.openapikyc.co.mz/v1/institutions/interest" \
-F "companyName=Banco Exemplo, S.A." \
-F "address=Av. Exemplo, 100, Maputo" \
-F "email=compliance@bancoexemplo.co.mz" \
-F "phoneNumber=+258840000000" \
-F "taxId=@./nuit.pdf" \
-F "licenseDocument=@./alvara.pdf" \
-F "commercialCertificate=@./certidao.pdf"Consultar estado da manifestação
GET/institutions/interest/{requestId}
Consulta pública por requestId. Estados: PENDING, APPROVED, REJECTED. Quando REJECTED, reason indica o motivo.
Requisitos
- Sem autenticação
Caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| requestId | string | Obrigatório | Identificador devolvido na submissão (REQ-…) |
curl -X GET "https://sandbox.openapikyc.co.mz/v1/institutions/interest/REQ-01J9ZP001A"Listar serviços disponíveis
GET/services
Devolve os serviços que a instituição pode subscrever, identificados por serviceCode.
Requisitos
- Perfil INSTITUTION
- Authorization
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
curl -X GET "https://sandbox.openapikyc.co.mz/v1/services" \
-H "Authorization: Bearer <accessToken>"Subscrever serviço
POST/services/subscriptions
Regista a intenção de uso do serviço. A subscrição fica INACTIVE até ser activada e ainda não gera apiKey.
Requisitos
- Perfil INSTITUTION
- Authorization
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
Corpo (application/json)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| serviceCode | enum | Obrigatório | VERIFICATION_SESSION, DOCUMENT_INTELLIGENCE, FACE_VERIFICATION, SMS, LIVENESS, SUBSCRIBER_CHECK |
| label | string | Opcional | Nome interno da subscrição |
curl -X POST "https://sandbox.openapikyc.co.mz/v1/services/subscriptions" \
-H "Authorization: Bearer <accessToken>" \
-H "Content-Type: application/json" \
-d '{"serviceCode":"FACE_VERIFICATION","label":"Onboarding"}'Activar chave do serviço
POST/services/subscriptions/{subscriptionId}/activate
Gera a apiKey para o ambiente indicado. SANDBOX e PRODUCTION são activadas separadamente.
Requisitos
- Perfil INSTITUTION
- Authorization
- PRODUCTION requer homologação prévia
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
Caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| subscriptionId | string | Obrigatório | SUB-… |
Corpo (application/json)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| environment | enum | Obrigatório | SANDBOX ou PRODUCTION |
Regras
A activação em SANDBOX gera automaticamente o MOU informativo associado, sem intervenção manual.
curl -X POST "https://sandbox.openapikyc.co.mz/v1/services/subscriptions/SUB-01J9ZMS8W2P9/activate" \
-H "Authorization: Bearer <accessToken>" \
-H "Content-Type: application/json" \
-d '{"environment":"SANDBOX"}'Listar subscrições
GET/services/subscriptions
Devolve as subscrições da instituição autenticada, com estado por ambiente.
Requisitos
- Perfil INSTITUTION
- Authorization
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
Pendente no contrato: O contrato não define o exemplo de resposta desta operação.
curl -X GET "https://sandbox.openapikyc.co.mz/v1/services/subscriptions" \
-H "Authorization: Bearer <accessToken>"Pendente: O contrato não define o exemplo de resposta desta operação.
Referência dos serviços
Analisar documento
POST/documents/analyze
Serviço isolado de leitura e extracção de dados de documentos de identificação.
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição DOCUMENT_INTELLIGENCE
- multipart/form-data
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição DOCUMENT_INTELLIGENCE |
| Idempotency-Key | uuid | Recomendado | UUID único por pedido facturável |
Corpo (multipart/form-data)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| clientReference | string | Obrigatório | Referência interna da instituição |
| documentType | enum | Opcional | NATIONAL_ID, PASSPORT, DRIVING_LICENCE, DIRE, VOTER_CARD |
| documentFront | file | Obrigatório | — |
| documentBack | file | Condicional | Obrigatório para NATIONAL_ID e DRIVING_LICENCE |
| returnPortrait | boolean | Opcional | Devolve o retrato recortado em base64 |
Regras
result pode ser CLEAR, CONSIDER (indício de adulteração) ou FAILED.
portrait só é devolvido quando returnPortrait é true.
curl -X POST "https://sandbox.openapikyc.co.mz/v1/documents/analyze" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11" \
-F "clientReference=PROP-2026-004417" \
-F "documentType=NATIONAL_ID" \
-F "documentFront=@./bi-frente.jpg" \
-F "documentBack=@./bi-verso.jpg" \
-F "returnPortrait=true"Comparar rosto
POST/biometrics/face-match
Compara uma selfie com uma imagem de referência. Cada verificação é guardada na base biométrica da instituição, permitindo detectar se o proponente já existe.
Indique a referência de uma de duas formas: envie o ficheiro reference, ou indique referenceDocumentId de um documento já analisado no OCR (DOC-…).
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição FACE_VERIFICATION
- multipart/form-data
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição FACE_VERIFICATION |
| Idempotency-Key | uuid | Recomendado | UUID único por pedido facturável |
Corpo (multipart/form-data)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| clientReference | string | Obrigatório | Referência interna da instituição |
| selfie | file | Obrigatório | — |
| reference | file | Condicional | Imagem de referência |
| referenceDocumentId | string | Condicional | Alternativa: ID de um documento já analisado (DOC-…) |
| checkExisting | boolean | Opcional | Se true, pesquisa 1:N na base da instituição. Por omissão true |
Regras
similarity é devolvido numa escala de 0 a 1 (por exemplo 0.984).
Quando existingIdentity é true, subscriberId identifica o registo já existente e o clientReference da submissão original fica disponível na consulta da verificação.
Erros aplicáveis
curl -X POST "https://sandbox.openapikyc.co.mz/v1/biometrics/face-match" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11" \
-F "clientReference=PROP-2026-004417" \
-F "selfie=@./selfie.jpg" \
-F "referenceDocumentId=DOC-01J9ZKQ83WPX"Consultar verificação facial
GET/biometrics/face-match/{checkId}
Devolve o resultado guardado de uma verificação facial anterior.
Requisitos
- X-API-Key da subscrição FACE_VERIFICATION
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição FACE_VERIFICATION |
Caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| checkId | string | Obrigatório | CHK-… |
Pendente no contrato: O contrato não define o exemplo de resposta desta operação.
curl -X GET "https://sandbox.openapikyc.co.mz/v1/biometrics/face-match/CHK-01J9ZKZM55RD" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo"Pendente: O contrato não define o exemplo de resposta desta operação.
Prova de vida isolada
POST/biometrics/liveness
Prova de vida sobre uma selfie, sem comparação com documento. Indicada para reautenticação de clientes já registados ou como passo prévio a outra verificação.
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição LIVENESS
- multipart/form-data
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição LIVENESS |
| Idempotency-Key | uuid | Recomendado | UUID único por pedido facturável |
Corpo (multipart/form-data)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| clientReference | string | Obrigatório | Referência interna da instituição |
| selfie | file | Obrigatório | Imagem do rosto (JPG, JPEG ou PNG) |
Regras
result: CLEAR, CONSIDER (indício de apresentação fraudulenta, a rever) ou FAILED.
FAILED devolve também o código LIVENESS_FAILED; sem rosto na imagem, FACE_NOT_DETECTED.
curl -X POST "https://sandbox.openapikyc.co.mz/v1/biometrics/liveness" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11" \
-F "clientReference=PROP-2026-004417" \
-F "selfie=@./selfie.jpg"Consultar prova de vida
GET/biometrics/liveness/{checkId}
Devolve o resultado guardado de uma prova de vida anterior, com o clientReference da submissão.
Requisitos
- X-API-Key da subscrição LIVENESS
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição LIVENESS |
Caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| checkId | string | Obrigatório | CHK-… |
Pendente no contrato: O contrato não define o exemplo de resposta desta operação.
curl -X GET "https://sandbox.openapikyc.co.mz/v1/biometrics/liveness/CHK-01J9ZM2LV7QA" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo"Pendente: O contrato não define o exemplo de resposta desta operação.
Criar sessão
POST/verifications
Fluxo KYC orquestrado: documento, face, prova de vida e telefone, com decisão consolidada. Recomendado para onboarding de clientes finais.
A criação devolve 202: o pedido foi aceite e é processado posteriormente. Consulte o resultado com GET /verifications/{sessionId}.
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição VERIFICATION_SESSION
- multipart/form-data
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição VERIFICATION_SESSION |
| Idempotency-Key | uuid | Recomendado | UUID único por pedido facturável |
Corpo (multipart/form-data)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| clientReference | string | Obrigatório | Única por sessão |
| firstName | string | Obrigatório | — |
| lastName | string | Obrigatório | — |
| dateOfBirth | date | Obrigatório | YYYY-MM-DD |
| phoneNumber | string | Condicional | Obrigatório se o check PHONE estiver activo |
| documentType | enum | Obrigatório | NATIONAL_ID, PASSPORT, DRIVING_LICENCE, DIRE, VOTER_CARD |
| documentFront | file | Obrigatório | — |
| documentBack | file | Condicional | Obrigatório para NATIONAL_ID e DRIVING_LICENCE |
| selfie | file | Obrigatório | — |
| checks | array | Opcional | DOCUMENT, FACE_MATCH, LIVENESS, PHONE. Por omissão, todas |
| checkExisting | boolean | Opcional | Pesquisa 1:N na base da instituição. Por omissão true |
curl -X POST "https://sandbox.openapikyc.co.mz/v1/verifications" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11" \
-F "clientReference=PROP-2026-004417" \
-F "firstName=Amélia José" \
-F "lastName=Cossa" \
-F "dateOfBirth=1992-03-14" \
-F "phoneNumber=+258840000000" \
-F "documentType=NATIONAL_ID" \
-F "documentFront=@./bi-frente.jpg" \
-F "documentBack=@./bi-verso.jpg" \
-F "selfie=@./selfie.jpg"Consultar sessão
GET/verifications/{sessionId}
Devolve o estado, a decisão consolidada e o resultado de cada check.
Requisitos
- X-API-Key da subscrição VERIFICATION_SESSION
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição VERIFICATION_SESSION |
Caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| sessionId | string | Obrigatório | VER-… |
Regras
Estados de sessão: AWAITING_INPUT, PROCESSING, APPROVED, DECLINED, REVIEW, EXPIRED.
Resultado de cada check: CLEAR, CONSIDER ou FAILED.
curl -X GET "https://sandbox.openapikyc.co.mz/v1/verifications/VER-01J9ZK7Q4T8MHV" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo"Listar sessões
GET/verifications
Lista paginada. A resposta contém data.items e data.hasMore.
Requisitos
- X-API-Key da subscrição VERIFICATION_SESSION
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição VERIFICATION_SESSION |
Query
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| limit | number | Opcional | Número de itens por página (ex.: 20) |
| startingAfter | string | Opcional | Cursor: sessionId a partir do qual continuar |
| sessionStatus | enum | Opcional | Filtro por estado |
| clientReference | string | Opcional | Filtro por referência |
| createdFrom | date | Opcional | Filtro por data de criação |
| createdTo | date | Opcional | Filtro por data de criação |
Pendente no contrato: O contrato indica apenas data.items e data.hasMore; o formato completo dos itens não está definido.
curl -X GET "https://sandbox.openapikyc.co.mz/v1/verifications?limit=20&startingAfter=VER-01J9ZK7Q4T8MHV" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo"Pendente: O contrato indica apenas data.items e data.hasMore; o formato completo dos itens não está definido.
Enviar SMS
POST/sms/send
Envia mensagens SMS ao proponente ou cliente final. Este serviço apenas envia: não valida códigos OTP.
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição SMS
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição SMS |
| Idempotency-Key | uuid | Recomendado | UUID único por pedido facturável |
Corpo (application/json)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| clientReference | string | Obrigatório | — |
| phoneNumber | string | Obrigatório | Formato E.164 |
| message | string | Opcional | Conteúdo da mensagem. Se omitido, usa o template padrão configurado no portal |
| templateId | string | Opcional | Template registado no portal |
Erros aplicáveis
curl -X POST "https://sandbox.openapikyc.co.mz/v1/sms/send" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11" \
-H "Content-Type: application/json" \
-d '{"clientReference":"PROP-2026-004417","phoneNumber":"+258840000000","message":"Mensagem de exemplo"}'Regras comuns
Verificação da titularidade e do risco do número móvel junto da operadora (Vodacom, Movitel, Tmcel). Cinco verificações independentes, cada uma com o seu endpoint e facturada por chamada.
Normalização: o número é normalizado para 258…; são aceites 84…, 0…, +258… e 258…. Tem de ter um prefixo móvel de 82 a 87; caso contrário, 422 PHONE_INVALID.
Decisão negativa: uma verificação concluída devolve HTTP 200 com data.passed e data.reasonCode. passed: false é um resultado negativo, não um erro técnico.
Privacidade: a resposta inclui o resultado, a operadora, o número mascarado e os indicadores, mas não os dados pessoais do titular devolvidos pela operadora.
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição SUBSCRIBER_CHECK
- Facturado por chamada
Motivos de decisão (reasonCode)
| Código | Descrição |
|---|---|
| SUBSCRIBER_HIGH_RISK | Número classificado como de alto risco pela operadora |
| SUBSCRIBER_SERVICE_INACTIVE | Serviço do número diferente do estado exigido |
| SUBSCRIBER_OWNERSHIP_UNCERTAIN | Titularidade incerta e acceptUncertain não activo |
| SUBSCRIBER_OWNERSHIP_REJECTED | Os dados não correspondem ao titular |
| OTP_RISK_CAUTION | Risco moderado e acceptCaution = false |
| OTP_RISK_HIGH | Risco elevado para envio de OTP |
| OTP_RISK_REJECTED | Envio de OTP desaconselhado pela operadora |
| RISK_SCORE_TOO_HIGH | level acima de maxLevel |
| RISK_SCORE_BLOCKED | action = BLOCK |
| BIO_PARTIAL_MATCH | Correspondência parcial e acceptPartial não activo |
| BIO_POSSIBLE_DUPLICATE | Possível duplicado na base da operadora |
| BIO_REJECTED | A biometria não corresponde ao titular |
841234567 → 258841234567
0841234567 → 258841234567
+258841234567 → 258841234567
258841234567 → 258841234567
Prefixos móveis aceites: 82 a 87Titular do número
POST/subscriber-check/number-owner
Confirma que o número está registado e activo na operadora e avalia a titularidade.
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição SUBSCRIBER_CHECK
- Facturado por chamada
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição SUBSCRIBER_CHECK |
| Idempotency-Key | uuid | Recomendado | UUID único por pedido facturável |
Corpo (application/json)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| clientReference | string | Obrigatório | Referência interna da instituição |
| phoneNumber | string | Obrigatório | Número móvel moçambicano: 84…, 0…, +258… ou 258…. Prefixo 82 a 87 |
| acceptUncertain | boolean | Opcional | Se true, OWNERSHIP_UNCERTAIN passa |
| requireActive | boolean | Opcional | Se true, exige o serviço do número em ACTIVE |
Regras
result: OWNERSHIP_CONFIRMED, OWNERSHIP_UNCERTAIN, OWNERSHIP_REJECTED ou HIGH_RISK.
HIGH_RISK falha sempre, mesmo com acceptUncertain.
curl -X POST "https://sandbox.openapikyc.co.mz/v1/subscriber-check/number-owner" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11" \
-H "Content-Type: application/json" \
-d '{"clientReference":"PROP-2026-004417","phoneNumber":"841234567","requireActive":true}'Titularidade do contacto
POST/subscriber-check/contact-verify
Compara os dados do cliente com o registo do titular na operadora.
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição SUBSCRIBER_CHECK
- Facturado por chamada
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição SUBSCRIBER_CHECK |
| Idempotency-Key | uuid | Recomendado | UUID único por pedido facturável |
Corpo (application/json)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| clientReference | string | Obrigatório | Referência interna da instituição |
| phoneNumber | string | Obrigatório | Número móvel moçambicano: 84…, 0…, +258… ou 258…. Prefixo 82 a 87 |
| firstName | string | Obrigatório | Nomes próprios |
| lastName | string | Obrigatório | Apelido |
| documentNumber | string | Obrigatório | N.º do documento de identificação (pelo menos um dígito) |
| dateOfBirth | date | Obrigatório | YYYY-MM-DD |
| acceptUncertain | boolean | Opcional | Se true, OWNERSHIP_UNCERTAIN passa |
| serviceState | enum | Opcional | Estado esperado do serviço. Por omissão ACTIVE |
Regras
Sem nome, documento ou data de nascimento válidos devolve 422 SUBSCRIBER_DATA_REQUIRED, com os campos em falta em errors.
Erros aplicáveis
curl -X POST "https://sandbox.openapikyc.co.mz/v1/subscriber-check/contact-verify" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11" \
-H "Content-Type: application/json" \
-d '{"clientReference":"PROP-2026-004417","phoneNumber":"861234521","firstName":"Nome","lastName":"Apelido","documentNumber":"000000000000A","dateOfBirth":"1990-01-01"}'Risco para OTP
POST/subscriber-check/otp-risk-check
Avalia se é seguro enviar um código OTP para o número (por exemplo, após troca recente de SIM).
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição SUBSCRIBER_CHECK
- Facturado por chamada
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição SUBSCRIBER_CHECK |
| Idempotency-Key | uuid | Recomendado | UUID único por pedido facturável |
Corpo (application/json)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| clientReference | string | Obrigatório | Referência interna da instituição |
| phoneNumber | string | Obrigatório | Número móvel moçambicano: 84…, 0…, +258… ou 258…. Prefixo 82 a 87 |
| checkLevel | enum | Opcional | P1, P2 ou P3. Por omissão P2 |
| acceptCaution | boolean | Opcional | Se true, SAFE_WITH_CAUTION passa. Por omissão true |
| fallbackLevel | boolean | Opcional | Se a operadora não tiver acordo para o nível, tenta o nível abaixo (P3 → P2 → P1). Por omissão true |
Regras
result: SAFE, SAFE_WITH_CAUTION ou risco elevado / rejeitado.
appliedLevel indica o nível efectivamente usado após o fallback; a Movitel só disponibiliza P1.
Sem nível disponível devolve 403 SUBSCRIBER_LEVEL_NOT_ALLOWED.
Erros aplicáveis
curl -X POST "https://sandbox.openapikyc.co.mz/v1/subscriber-check/otp-risk-check" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11" \
-H "Content-Type: application/json" \
-d '{"clientReference":"PROP-2026-004417","phoneNumber":"861234521","checkLevel":"P2"}'Score de risco
POST/subscriber-check/risk-score
Devolve o nível de risco do número para o contexto de uso indicado.
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição SUBSCRIBER_CHECK
- Facturado por chamada
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição SUBSCRIBER_CHECK |
| Idempotency-Key | uuid | Recomendado | UUID único por pedido facturável |
Corpo (application/json)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| clientReference | string | Obrigatório | Referência interna da instituição |
| phoneNumber | string | Obrigatório | Número móvel moçambicano: 84…, 0…, +258… ou 258…. Prefixo 82 a 87 |
| maxLevel | enum | Opcional | LOW, MEDIUM ou HIGH. Nível máximo aceite. Por omissão MEDIUM |
| dataLevel | enum | Opcional | P1, P2 ou P3 |
| context | enum | Opcional | KYC, OTP, PAYMENT ou ONBOARDING |
| fallbackLevel | boolean | Opcional | Como no Risco para OTP. Por omissão true |
Regras
Passa quando level é igual ou inferior a maxLevel e action é diferente de BLOCK.
curl -X POST "https://sandbox.openapikyc.co.mz/v1/subscriber-check/risk-score" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11" \
-H "Content-Type: application/json" \
-d '{"clientReference":"PROP-2026-004417","phoneNumber":"821234545","maxLevel":"MEDIUM","context":"KYC"}'Biometria na operadora
POST/subscriber-check/bio-verify
Compara a selfie e o documento com a fotografia de registo do titular na operadora.
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição SUBSCRIBER_CHECK
- Facturado por chamada
- multipart/form-data
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição SUBSCRIBER_CHECK |
| Idempotency-Key | uuid | Recomendado | UUID único por pedido facturável |
Corpo (multipart/form-data)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| clientReference | string | Obrigatório | Referência interna da instituição |
| phoneNumber | string | Obrigatório | Número móvel moçambicano: 84…, 0…, +258… ou 258…. Prefixo 82 a 87 |
| selfie | file | Obrigatório | — |
| documentFront | file | Obrigatório | Frente do documento de identificação |
| acceptPartial | boolean | Opcional | Se true, PARTIAL_MATCH passa |
Regras
result: VERIFIED, PARTIAL_MATCH, possível duplicado ou rejeitado.
Titular sem fotografia de registo na operadora devolve 422 SUBSCRIBER_BIOMETRY_NOT_FOUND.
Erros aplicáveis
SELFIE_REQUIREDDOCUMENT_REQUIREDSUBSCRIBER_BIOMETRY_NOT_FOUND
curl -X POST "https://sandbox.openapikyc.co.mz/v1/subscriber-check/bio-verify" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo" \
-H "Idempotency-Key: 3f6c1d2e-8a4b-4c1e-9f7a-2b5d8e0c1a11" \
-F "clientReference=PROP-2026-004417" \
-F "phoneNumber=841234567" \
-F "selfie=@./selfie.jpg" \
-F "documentFront=@./bi-frente.jpg"Consultar verificação
GET/subscriber-check/{checkId}
Devolve o resultado guardado de qualquer verificação Subscriber Check anterior, com o clientReference da submissão.
Requisitos
- Perfil INSTITUTION
- X-API-Key da subscrição SUBSCRIBER_CHECK
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| X-API-Key | string | Obrigatório | Chave activa da subscrição SUBSCRIBER_CHECK |
Caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| checkId | string | Obrigatório | SBC-… |
Pendente no contrato: O contrato não define o exemplo de resposta desta operação.
curl -X GET "https://sandbox.openapikyc.co.mz/v1/subscriber-check/SBC-01J9ZN4A1K2P" \
-H "Authorization: Bearer <accessToken>" \
-H "X-API-Key: ky_sbx_exemplo"Pendente: O contrato não define o exemplo de resposta desta operação.
Conta
Consultar saldo
GET/account/balance
Devolve o plano, o modo de facturação e o saldo disponível da instituição.
Requisitos
- Perfil INSTITUTION
- Authorization
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
curl -X GET "https://sandbox.openapikyc.co.mz/v1/account/balance" \
-H "Authorization: Bearer <accessToken>"Extracto de consumo
GET/account/usage
Totais por serviço e por dia em data.items. Para exportar em CSV, envie o header Accept: text/csv.
Requisitos
- Perfil INSTITUTION
- Authorization
Headers
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | Obrigatório | Bearer <accessToken> |
| Accept | string | Opcional | text/csv para exportar em CSV |
Query
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| from | date | Não definido | Data inicial (YYYY-MM-DD) |
| to | date | Não definido | Data final (YYYY-MM-DD) |
Pendente no contrato: O contrato não define a estrutura de data.items, as colunas do CSV nem a obrigatoriedade de from e to.
curl -X GET "https://sandbox.openapikyc.co.mz/v1/account/usage?from=2026-07-01&to=2026-07-09" \
-H "Authorization: Bearer <accessToken>" \
-H "Accept: text/csv" \
-o consumo.csvPendente: O contrato não define a estrutura de data.items, as colunas do CSV nem a obrigatoriedade de from e to.
Solicitar acesso
Prefere falar connosco antes de submeter a manifestação de interesse? Deixe os seus dados.
