responsiblo

Para programadores

API para parceiros

Envie-nos um cliente com o seu próprio identificador pseudónimo - sem e-mail, nome ou outros dados pessoais - e consulte a qualquer momento o estado da sua formação. Serve como verificação de conformidade antes de um contrato, de um depósito ou de um pagamento.

Versão 1.3.2 · JSON sobre HTTPS · OpenAPI

Como funciona

A API é igual para todos os parceiros. Em cinco passos:

  1. Ativamos a API para a sua empresa; na sua administração, cria uma chave API no separador API.
  2. Quando um cliente deve receber formação, o seu sistema chama POST /v1/users com o seu identificador do cliente.
  3. Criamos um perfil sem e-mail e devolvemos um link de acesso (entryUrl); mostra-o ao cliente como um botão.
  4. O cliente clica nele e entra diretamente no curso.
  5. Consulta o estado a qualquer momento através de GET /v1/users/{identifier}, ou comunicamo-lo ao seu servidor por webhook.

Quanto ao identificador, é o responsável pelo tratamento; nós tratamos apenas dados pseudonimizados. Nunca envie como identificador um e-mail ou um nome - a API recusa um endereço de e-mail com o erro 422.

Endereço e autenticação

Cada chamada vai por HTTPS para o endereço abaixo e leva a sua chave API no cabeçalho Authorization.

https://api.responsiblo.com
Authorization: Bearer rsb_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  • rsb_live_... abre o seu programa de produção, rsb_test_... o seu programa de teste (sandbox).
  • A chave é mostrada apenas uma vez, quando é criada; guardamos apenas a sua impressão digital. Guarde-a como segredo no seu servidor - nunca num navegador nem numa aplicação.
  • A chave tem permissões: read (o estado e a lista de pessoas, o certificado) e write (o envio e a anonimização de pessoas). Pode estar limitada aos seus endereços IP e ter uma validade.
  • Substituição: cria uma chave nova, a antiga continua válida durante 7 dias e depois expira.
  • As respostas nunca são guardadas em cache (Cache-Control: no-store) e a API não aceita chamadas a partir de um navegador (sem CORS).

POST /v1/users

Envia uma pessoa para o programa da chave (permissão write).

curl -X POST https://api.responsiblo.com/v1/users \
  -H "Authorization: Bearer $RSB_KEY" \
  -H "Content-Type: application/json" \
  -d '{"identifier":"client-48213","language":"cs","label":"campaign-2026-10"}'
CampoObrigatórioSignificado
identifier sim O seu pseudónimo da pessoa, 1 a 64 caracteres A-Z a-z 0-9 . _ : @ -; nunca um endereço de e-mail (recusado com 422).
program não Código do programa; se o indicar, tem de ser o programa da chave.
language não Idioma do curso (cs, en, ...); por predefinição, o primeiro idioma do programa.
label não A sua etiqueta - uma coorte ou uma campanha, 1 a 64 caracteres, nunca um dado pessoal.
expiresAt não Último dia de acesso, AAAA-MM-DD.

201 Created para uma pessoa nova, 200 OK quando o identificador já existe - nada muda, a chamada pode ser repetida em segurança. O corpo é o estado abaixo, com entryUrl. Um limite esgotado de pessoas ou de licenças do programa devolve 403.

GET /v1/users/{identifier}

Estado de uma pessoa (permissão read): o que uma verificação de conformidade precisa, nada mais.

curl https://api.responsiblo.com/v1/users/client-48213 -H "Authorization: Bearer $RSB_KEY"

{
  "identifier": "client-48213",
  "program": "your-program",
  "status": "in_progress",
  "progress": 43,
  "lessonsCompleted": 3,
  "lessonsTotal": 7,
  "quizScore": null,
  "label": "campaign-2026-10",
  "createdAt": "2026-10-20T10:02:11Z",
  "startedAt": "2026-10-20T10:05:40Z",
  "completedAt": null,
  "lastActivityAt": "2026-10-20T10:31:40Z",
  "expiresAt": null,
  "certificate": null,
  "entryUrl": "https://your-company.responsiblo.com/entry/..."
}
statusSignificado
enrolled enviada, ainda não entrou
started entrou, ainda não concluiu nada
in_progress tem lições concluídas, o programa ainda não
completed o programa está concluído (completedAt)
expired o acesso terminou (expiresAt passou; uma pessoa na sandbox termina ao fim de 7 dias)

quizScore é o resultado do questionário final em %, assim que estiver concluído. As horas estão em UTC, ao segundo inteiro. O campo certificate contém o certificado da pessoa (ver abaixo); enquanto não o tiver, é null.

?include=detail

Acrescenta o progresso em cada curso e o resultado de cada questionário - nunca as respostas individuais.

"courses": [{"id": "733db340-...", "name": "Introduction", "progress": 40, "lessonsCompleted": 2, "lessonsTotal": 5, "completed": false}],
"quizzes": [{"id": "d2e72fd7-...", "name": "Quiz of the introduction", "score": 85, "completedAt": "2026-10-20T10:31:40Z"}]

GET /v1/users

Lista das pessoas que enviou para o programa da chave (permissão read), página a página: cada item tem a forma do estado acima. Opcionalmente status (apenas as pessoas nesse estado), limit (1 a 500, por predefinição 100) e cursor.

curl "https://api.responsiblo.com/v1/users?status=completed&limit=100" -H "Authorization: Bearer $RSB_KEY"

{
  "items": [{ "identifier": "client-48213", "status": "completed", "...": "the state of GET /v1/users/{identifier}" }],
  "nextCursor": "MjAyNi0xMC0yMFQxMDowMjoxMVp8...",
  "limit": 100
}

curl "https://api.responsiblo.com/v1/users?status=completed&limit=100&cursor=MjAyNi0xMC0yMFQxMDowMjoxMVp8..." -H "Authorization: Bearer $RSB_KEY"
  • Continue com cursor = nextCursor enquanto nextCursor não for null; o cursor é um texto opaco, nunca o construa por si.
  • As pessoas surgem pelo momento do envio, numa ordem estável (também no mesmo momento), nenhuma duas vezes; as pessoas anonimizadas não constam da lista.
  • Com o filtro status percorremos no máximo 2000 pessoas por página, pelo que uma página pode ter menos itens do que limit, ou mesmo nenhum - continue enquanto houver um nextCursor.

Certificado da pessoa

Assim que a pessoa conclui o programa, o curso emite-lhe um certificado - com o seu pseudónimo (a alcunha do perfil ID XXXXXX), sem nome e sem e-mail. Nada é enviado por e-mail; o estado da pessoa inclui o campo certificate com o número, as datas e a página pública de verificação, e o PDF é descarregado através de GET /v1/users/{identifier}/certificate.

"certificate": {
  "number": "RSP-7KQ2-M4XH-9TWB",
  "issuedAt": "2026-10-20T10:39:15Z",
  "expiresAt": "2028-10-20T10:39:12Z",
  "verifyUrl": "https://responsiblo.com/verify/RSP-7KQ2-M4XH-9TWB"
}

curl https://api.responsiblo.com/v1/users/client-48213/certificate -H "Authorization: Bearer $RSB_KEY" -o client-48213.pdf
  • A página de verificação verifyUrl mostra apenas o pseudónimo, o programa, o parceiro e a validade - nunca o seu identificador.
  • O PDF devolve application/pdf (permissão read). Sem certificado, a resposta é 404 certificateNotFound; enquanto o PDF ainda está a ser gerado, 404 certificatePdfNotReady com Retry-After.
  • Um certificado revogado nunca é entregue (o campo certificate fica então null, o PDF 404); um certificado com a validade expirada continua a ser uma prova verdadeira e é entregue.
  • Um webhook anuncia o certificado com o evento certificate.issued (logo após user.completed).

DELETE /v1/users/{identifier}

Anonimiza uma pessoa (permissão write): do perfil desaparecem o seu identificador, a etiqueta e todas as mensagens de webhook que o mencionam; os links de acesso deixam de ser válidos. O certificado e o resultado do curso ficam sob o número do certificado - como prova de conformidade.

curl -X DELETE https://api.responsiblo.com/v1/users/client-48213 -H "Authorization: Bearer $RSB_KEY"

HTTP/1.1 204 No Content

Resposta 204 sem corpo; cada chamada seguinte com o mesmo identificador devolve 404 userNotFound, pelo que a repetição é segura. Pode depois voltar a enviar o mesmo identificador como uma pessoa nova.

Link de acesso

Mostre entryUrl à pessoa (um botão Iniciar o curso no seu sistema). Inicia a sessão da pessoa no curso - sem e-mail e sem palavra-passe.

O link é válido durante 30 dias e pode ser usado várias vezes; cada chamada GET /v1/users/{identifier} devolve um novo. Nunca o envie a outra pessoa: quem tem o link entra como essa pessoa.

Webhooks

No separador API da sua administração, configura um webhook por programa: um endereço HTTPS público do seu servidor e os eventos. A partir daí enviamos-lhe um POST com JSON - apenas identificadores e estados, nunca o link de acesso.

EventoQuando
user.enrolled a pessoa foi enviada (a primeira vez que o seu webhook a conhece)
user.started a pessoa entrou no curso
user.completed a pessoa concluiu o programa
certificate.issued a pessoa obteve um certificado; data contém certificate (o número, as datas, verifyUrl)
user.expired o acesso da pessoa terminou
POST https://your-server.example/responsiblo/webhook
Content-Type: application/json
X-Responsiblo-Event: user.completed
X-Responsiblo-Delivery: 5b0c1f9e-2d1a-4a57-9a3e-0d6c9c1f2b77
X-Responsiblo-Signature: t=1792492800,v1=3f1c...e9

{
  "id": "5b0c1f9e-2d1a-4a57-9a3e-0d6c9c1f2b77",
  "type": "user.completed",
  "createdAt": "2026-10-20T10:40:00Z",
  "apiVersion": "1.3.2",
  "program": "your-program",
  "data": {
    "identifier": "client-48213",
    "status": "completed",
    "progress": 100,
    "lessonsCompleted": 7,
    "lessonsTotal": 7,
    "quizScore": 85,
    "label": "campaign-2026-10",
    "startedAt": "2026-10-20T10:05:40Z",
    "completedAt": "2026-10-20T10:39:12Z",
    "expiresAt": null
  }
}

Assinatura

Cada mensagem leva o cabeçalho X-Responsiblo-Signature: t=<tempo Unix>,v1=<HMAC-SHA256 do texto t.corpo com o segredo do webhook, hex>. O segredo (whsec_...) é mostrado uma vez, quando o webhook é criado. Antes de confiar numa mensagem, verifique a assinatura e a idade de t; use X-Responsiblo-Delivery como chave de idempotência.

// PHP: $secret = "whsec_...", $header = X-Responsiblo-Signature, $body = the raw body
preg_match('/^t=(\d+),v1=([0-9a-f]{64})$/', $header, $m);
$valid = $m
    && abs(time() - (int) $m[1]) <= 300
    && hash_equals(hash_hmac('sha256', $m[1] . '.' . $body, $secret), $m[2]);

Entrega e repetição

Entregue = resposta 2xx em 10 segundos. Caso contrário, tentamos de novo ao fim de 1 minuto, 5 minutos, 30 minutos, 2 horas e 12 horas, e depois desistimos. Não seguimos redirecionamentos.

20 mensagens não entregues seguidas desativam o webhook até que o volte a ativar; as mensagens desse período ficam à espera. O botão Test envia um ping; o registo de entregas encontra-se na sua administração.

O evento certificate.issued acrescenta-se a um webhook nas respetivas definições; um webhook criado antes da versão 1.2 não o recebe por si só.

Erros

Cada erro tem uma única forma: status, code, reason e message; um erro 422 acrescenta errors (campo - o que está errado).

{ "status": "error", "code": 422, "reason": "invalidBody", "message": "The body is not valid.",
  "errors": { "identifier": "identifier must be a pseudonym of the partner, never an e-mail address" } }
HTTPreasonO que fazer
400 invalidJson envie um único objeto JSON
401 missingToken, invalidToken envie uma chave válida (uma chave revogada e uma expirada têm o mesmo aspeto); o cabeçalho WWW-Authenticate indica Bearer
403 scopeDenied, ipNotAllowed, apiDisabled, partnerInactive, spaceUnavailable, httpsRequired, userLimitReached, seatsExhausted a chave não tem permissão para isto, a API está desativada para a sua empresa, ou o programa está cheio
404 userNotFound, notFound no programa da chave não existe nenhuma pessoa com este identificador (nem anonimizada)
404 certificateNotFound, certificatePdfNotReady a pessoa ainda não tem certificado, ou o PDF está a ser gerado - tente de novo após Retry-After
409 identifierTaken o identificador pertence a uma pessoa de outro programa
422 invalidBody, invalidParameter ver errors (um campo do corpo ou um parâmetro da consulta - o que está errado)
429 rateLimited aguarde Retry-After segundos
500 internalError tente mais tarde; indique incidentId ao nosso apoio

Para programas e agentes

  • Decida com base em code e reason, nunca no texto de message; errors é um objeto campo -> o que está errado.
  • Repita apenas 429, 500 e certificatePdfNotReady, e só após Retry-After segundos (caso contrário, com um intervalo crescente); não repita outros 4xx além de 429 sem corrigir a chamada.
  • POST /v1/users é idempotente por identifier (201 da primeira vez, depois 200); DELETE devolve 204 da primeira vez e 404 depois - ambas podem ser repetidas em segurança.
  • Elimine duplicados dos webhooks por X-Responsiblo-Delivery; a ordem das mensagens não é garantida, decide o estado em data.

Guia do empréstimo

O guia do empréstimo é um curso curto para o requerente junto de um mutuante: antes de assinar o contrato, o requerente percorre três lições, oito situações práticas e, eventualmente, um questionário, tudo com os números da sua própria proposta, e no fim confirma a proposta. Em cada ecrã, o requerente pode pedir uma explicação. Envia a proposta através da API, recebe um link de acesso e um webhook comunica-lhe o resultado.

Ativamos o guia do empréstimo mediante acordo consigo.

Também aqui o requerente é apenas o seu perfil pseudónimo de POST /v1/users. A proposta é identificada pelas suas referências (externalApplicationId, offerReference) e os documentos apenas por um link com impressão digital SHA-256 - nunca um nome, e-mail, número de identificação pessoal, número de conta ou telefone. responsiblo não aprova o empréstimo, não descarrega nem guarda os documentos, não verifica a identidade e não emite certificado para o guia.

  1. Cria o perfil do requerente: POST /v1/users com o seu pseudónimo.
  2. Envia a proposta: POST /v1/users/{identifier}/loan-offers; a resposta 201 traz entryUrl.
  3. Entrega entryUrl ao requerente pelo seu próprio canal autenticado. O link é válido durante 30 dias e pode ser usado várias vezes; o guia mostra os números da proposta do requerente.
  4. O fim é-lhe comunicado por webhook (loanGuide.completed, loanGuide.assistanceRequested e outros).
  5. Consulta o estado através de GET …/loan-offers/{offerReference} e o registo para o seu processo através de GET …/evidence. Proposta alterada = nova proposta com supersedes, pedido retirado = POST …/cancel.

Até à ativação, as operações do guia respondem 404 notFound ou 409 loanGuideNotConfigured. A permissão write envia e cancela a proposta, read lê o estado e o registo.

POST /v1/users/{identifier}/loan-offers

Envia uma proposta para o perfil do requerente (permissão write). O cabeçalho opcional Idempotency-Key tem 1 a 255 caracteres ASCII visíveis. Exemplo: empréstimo de 10 000 CZK, 10 800 CZK a pagar num único pagamento 30 dias após o desembolso, TAEG 155,10 %.

curl -X POST https://api.responsiblo.com/v1/users/applicant-30417/loan-offers \
  -H "Authorization: Bearer $RSB_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: offer-30417-1" \
  -d '{
  "externalApplicationId": "APP-30417",
  "offerReference": "OFF-30417-1",
  "locale": "cs-CZ",
  "currency": "CZK",
  "principalMinor": 1000000,
  "disbursedAmountMinor": 1000000,
  "totalPayableMinor": 1080000,
  "aprPercent": "155.10",
  "interestRate": { "percent": "8", "period": "month" },
  "repayment": {
    "type": "singlePayment",
    "amountMinor": 1080000,
    "due": { "kind": "relative", "days": 30, "anchor": "disbursement" }
  },
  "documents": [
    { "role": "precontract_information", "reference": "DOC-PRE-30417", "title": "Předsmluvní informace",
      "url": "https://documents.lender.example/pre/30417.pdf",
      "sha256": "623f4a37e444268c076896d6c2f389b46f568d1a26539b013f2ba25d03846f72" },
    { "role": "contract_package", "reference": "DOC-CON-30417", "title": "Smlouva a podmínky",
      "url": "https://documents.lender.example/contract/30417.pdf",
      "sha256": "9c7bfe0077d1189914f0e1c483c961f4c5b36e9892385f3d2ab6168e0c088aa6" }
  ],
  "validUntil": "2026-11-15T18:00:00Z"
}'

HTTP/1.1 201 Created

{
  "offerReference": "OFF-30417-1",
  "externalApplicationId": "APP-30417",
  "offerStatus": "active",
  "guideStatus": "created",
  "validUntil": "2026-11-15T18:00:00Z",
  "snapshotSha256": "8055bfa3c5f2c163691b85785eaf61221169a123bed67aff2c1dbaf2a8e44e7e",
  "entryUrl": "https://your-company.responsiblo.com/entry/...",
  "createdAt": "2026-11-10T09:14:05Z"
}
CampoObrigatórioSignificado
externalApplicationId sim O seu número do pedido, 1 a 128 caracteres A-Z a-z 0-9 . _ : -; nunca um endereço de e-mail.
offerReference sim A sua referência da proposta, as mesmas regras que externalApplicationId.
locale sim Língua e país do guia: cs-CZ.
currency sim Moeda: CZK.
principalMinor sim Montante do empréstimo em haléř (centésimos de coroa), número inteiro de 1 a 10 000 000 000.
disbursedAmountMinor sim Montante desembolsado em haléř; tem de ser igual ao montante do empréstimo.
totalPayableMinor sim Montante total a pagar em haléř; no mínimo o montante do empréstimo e exatamente a soma dos pagamentos.
aprPercent sim TAEG em percentagem como texto ("155.10"), calculada e garantida por si. Custos positivos com TAEG 0 são recusados pela API.
interestRate não Taxa de juro {percent, period}, period = year, month ou day.
repayment sim Reembolso: singlePayment {amountMinor, due} com data (kind date) ou número de dias desde o desembolso (kind relative, 1 a 365), ou installments {schedule: [{date, amountMinor}]} com 1 a 360 prestações por ordem crescente, nenhuma no passado. O tipo tem de corresponder ao produto definido para o seu guia.
documents sim 2 a 10 documentos {role, reference, title, url, sha256}; cobertos os papéis que as definições do seu guia exigem (por predefinição precontract_information e contract_package). url apenas HTTPS num host autorizado nas definições do seu guia, no máximo 2 048 caracteres, sem credenciais; sha256 = 64 caracteres hexadecimais declarados por si.
validUntil sim Validade da proposta, RFC 3339 com desvio horário, no futuro e no máximo 7 dias à frente.
supersedes não offerReference da proposta ativa do mesmo perfil que a nova proposta substitui.
returnUrl não Opcional: o endereço para onde a página «Concluído» devolve o requerente no fim do guia. Apenas HTTPS absoluto, no máximo 2048 caracteres, sem credenciais; substituímos os símbolos {offerReference} e {externalApplicationId} pelas referências da proposta. Sem ele aplica-se o endereço de regresso das definições do seu guia.

O mesmo corpo novamente (com as mesmas referências ou a mesma Idempotency-Key) devolve 200 com a proposta existente e um novo entryUrl; outro corpo com elas devolve 409 offerConflict. Um perfil tem uma proposta ativa: outra sem supersedes devolve 409 activeOfferExists, um supersedes errado 409 notSupersedable. As definições do seu guia (questionário, contacto) ficam nesse momento bloqueadas para a proposta.

Estado, registo e cancelamento

  • GET /v1/users/{identifier}/loan-offers/{offerReference} - estado (permissão read): offerStatus (active, expired, superseded, cancelled), guideStatus (created, in_progress, completed), lições concluídas, prática, questionário (null quando está desativado) e os momentos da apresentação da proposta, da confirmação e do pedido de explicação. Nunca as respostas, os valores da proposta nem o link. A conclusão mantém-se, mesmo que a proposta expire mais tarde.
  • GET /v1/users/{identifier}/loan-offers/{offerReference}/evidence - registo para o seu processo (permissão read): schemaVersion loan-guide-evidence/1, instantâneo da sua proposta com a impressão digital snapshotSha256, edição do curso com as impressões digitais das lições, eventos pela ordem de sequence, cada resposta com todas as tentativas, a confirmação e limitations - o que o registo não prova (apresentado não significa lido, a identidade é afirmada por si, documentos apenas por referência, nenhum certificado, nenhuma aprovação do empréstimo).
  • POST /v1/users/{identifier}/loan-offers/{offerReference}/cancel - cancela uma proposta ativa (permissão write), reasonCode = withdrawn_by_provider ou application_closed; 200 devolve o estado, uma proposta que não está ativa ou cujo guia está concluído devolve 409 notActive.
curl https://api.responsiblo.com/v1/users/applicant-30417/loan-offers/OFF-30417-1 -H "Authorization: Bearer $RSB_KEY"

{
  "offerReference": "OFF-30417-1",
  "externalApplicationId": "APP-30417",
  "offerStatus": "active",
  "guideStatus": "completed",
  "quizEnabled": true,
  "lessonsCompleted": 3,
  "lessonsTotal": 3,
  "practiceCompleted": true,
  "quizPassed": true,
  "offerPresentedAt": "2026-11-10T18:32:47Z",
  "confirmedAt": "2026-11-10T18:34:02Z",
  "completedAt": "2026-11-10T18:34:02Z",
  "assistanceRequested": false,
  "assistanceRequestedAt": null,
  "validUntil": "2026-11-15T18:00:00Z",
  "evidenceErased": false,
  "...": "..."
}

curl -X POST https://api.responsiblo.com/v1/users/applicant-30417/loan-offers/OFF-30417-1/cancel \
  -H "Authorization: Bearer $RSB_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reasonCode":"withdrawn_by_provider"}'

?externalApplicationId= só é necessário quando uma offerReference pertence a vários pedidos do perfil (caso contrário, 409 ambiguousOfferReference).

Webhooks do guia

O webhook do programa (ver Webhooks) recebe os eventos do guia sem subscrição própria. A assinatura, a entrega e a repetição são as mesmas dos outros eventos; data contém identifier, offerReference, externalApplicationId, guideStatus, occurredAt e sequence (a ordem dos eventos de uma proposta) - nunca o registo, os valores da proposta nem o link de acesso.

EventoQuando
loanGuide.completed o requerente percorreu o guia e confirmou a proposta
loanGuide.assistanceRequested o requerente pediu uma explicação (ligue ao requerente)
loanGuide.expired o validUntil da proposta foi ultrapassado
loanGuide.superseded uma nova proposta substituiu-a (supersedes)
loanGuide.cancelled cancelou a proposta
POST https://your-server.example/responsiblo/webhook
Content-Type: application/json
X-Responsiblo-Event: loanGuide.completed
X-Responsiblo-Delivery: 0f6e2a4c-91d3-4b8e-a7c5-3e2d1b9f6a08
X-Responsiblo-Signature: t=1794335647,v1=8b2d...4c

{
  "id": "0f6e2a4c-91d3-4b8e-a7c5-3e2d1b9f6a08",
  "type": "loanGuide.completed",
  "createdAt": "2026-11-10T18:34:07Z",
  "apiVersion": "1.3.2",
  "program": "your-program",
  "data": {
    "identifier": "applicant-30417",
    "offerReference": "OFF-30417-1",
    "externalApplicationId": "APP-30417",
    "guideStatus": "completed",
    "occurredAt": "2026-11-10T18:34:02Z",
    "sequence": 23
  }
}

Cada evento chega a um webhook no máximo uma vez (chave de idempotência = X-Responsiblo-Delivery). Um webhook criado mais tarde não reproduz eventos anteriores, e os eventos com mais de 28 dias já não são comunicados.

Conservação do registo

Quando o percurso de uma proposta termina (proposta concluída, cancelada, expirada ou substituída), corre o prazo de conservação das definições do seu guia (por predefinição 30 dias). Depois, o registo é apagado: GET …/evidence devolve 410 evidenceErased e o estado continua a responder com evidenceErased: true, as referências e os momentos. Uma proposta ativa nunca é apagada. Descarregue o registo que tem de conservar logo após loanGuide.completed.

Erros do guia

Os erros têm a forma da API acima. Além disso, para o guia:

HTTPreasonO que fazer
404 offerNotFound o perfil não tem essa proposta (userNotFound = o perfil não existe)
409 offerConflict, activeOfferExists, notSupersedable as referências ou a Idempotency-Key já pertencem a outro corpo, ou o perfil tem outra proposta ativa - envie supersedes
409 loanGuideNotConfigured o guia não está ativado para o seu programa - escreva-nos
409 ambiguousOfferReference acrescente ?externalApplicationId=
409 notActive a proposta não está ativa ou o seu guia está concluído
410 evidenceErased o registo foi apagado após o prazo de conservação, o estado mantém-se
422 invalidOffer errors = {caminho: código[,código]} com o caminho no corpo (repayment.schedule[2].date, documents[0].url); os códigos na tabela abaixo
422 invalidBody supersedes, Idempotency-Key ou corpo do cancelamento
errorsCódigos do erro invalidOffer
required o campo está em falta
invalidFormat forma errada (tipo, padrão, comprimento, link sem HTTPS ou com credenciais)
outOfRange fora do intervalo permitido (montante, número de documentos, de prestações ou de dias)
notEqualPrincipal o montante desembolsado não é igual ao montante do empréstimo
sumMismatch a soma dos pagamentos não é igual ao montante total a pagar
belowPrincipal o montante total a pagar é inferior ao montante do empréstimo
aprContradiction TAEG 0 com custos positivos
typeMismatch o tipo de reembolso não corresponde ao produto definido para o seu guia
missingRole falta um documento com um papel que as definições do seu guia exigem
hostNotAllowed o link de um documento aponta para um host que as definições do seu guia não autorizam
notAscending as datas das prestações não são crescentes ou repetem-se
inPast a data de uma prestação ou validUntil está no passado
tooFar validUntil está mais de 7 dias à frente
unsupported valor não suportado (locale, currency, type, period, kind)
unknownField campo que a API não conhece
looksLikeEmail a referência parece um endereço de e-mail

Um erro nunca repete um valor que enviou. Exemplo: a mesma proposta com um pagamento de 10 700 CZK em vez de 10 800 CZK e uma validade de 9 dias:

"repayment": { "type": "singlePayment", "amountMinor": 1070000, "due": { "kind": "relative", "days": 30, "anchor": "disbursement" } },
"validUntil": "2026-11-19T18:00:00Z"

HTTP/1.1 422 Unprocessable Entity

{
  "status": "error",
  "code": 422,
  "reason": "invalidOffer",
  "message": "The offer contains invalid data.",
  "errors": {
    "repayment.amountMinor": "sumMismatch",
    "validUntil": "tooFar"
  }
}

Limites

120 chamadas por minuto e por chave. Após 30 chaves recusadas a partir de um mesmo endereço em dez minutos, o endereço aguarda 10 minutos.

Conservamos o registo de chamadas (sem corpos, o identificador apenas como impressão digital SHA-256) durante 180 dias, e as mensagens de webhook entregues e abandonadas durante 30 dias.

Estado e contrato

  • GET /v1/status - sem chave, devolve {"status":"ok","version":"1.3.2"}
  • GET /openapi - sem chave, o documento OpenAPI 3 da API para parceiros

Sandbox

A chave de teste rsb_test_... abre o seu programa de teste com o mesmo curso. As pessoas nele terminam ao fim de 7 dias; o webhook do programa de teste está separado do de produção.

Histórico de versões

  • 1.3.2 (2026-11) - Cada operação do documento OpenAPI tem um nome e uma descrição, e as operações estão organizadas em grupos. /v1/status e os webhooks indicam a versão 1.3.2. A forma dos pedidos e das respostas mantém-se inalterada.
  • 1.3.1 (2026-10) - Correções sem alteração dos endpoints nem das suas respostas.
  • 1.3.0 (2026-10) - Guia do empréstimo: POST /v1/users/{identifier}/loan-offers, estado, registo e cancelamento da proposta, webhooks loanGuide.*, conservação do registo. Campo opcional returnUrl da proposta (endereço de regresso próprio).
  • 1.2.0 (2026-10) - GET /v1/users com paginação, o certificado da pessoa (campo certificate, GET /v1/users/{identifier}/certificate, evento certificate.issued), DELETE /v1/users/{identifier} (anonimização), identificador com 64 caracteres no máximo, conservação do registo.
  • 1.1.0 (2026-10) - Chaves API, POST /v1/users, GET /v1/users/{identifier} com ?include=detail, link de acesso, webhooks, uma única forma de erros, estado público e OpenAPI, limites.
  • 1.0.0 (2024) - GET /v1/user/{identifier} com o JWT da chave de parceiro.

Quer a API para a sua empresa? Escreva-nos