Para desarrolladores
API para socios
Envíenos un cliente con su propio identificador seudónimo - sin correo electrónico, nombre ni otros datos personales - y consulte en cualquier momento el estado de su formación. Sirve como control de cumplimiento normativo antes de un contrato, un depósito o un pago.
Versión 1.3.2 · JSON sobre HTTPS · OpenAPI
Cómo funciona
La API es la misma para todos los socios. En cinco pasos:
- Activamos la API para su empresa; en su administración, usted crea una clave API en la pestaña API.
- Cuando un cliente deba formarse, su sistema llama a POST /v1/users con su identificador del cliente.
- Creamos un perfil sin correo electrónico y devolvemos un enlace de acceso (entryUrl); usted se lo muestra al cliente como un botón.
- El cliente hace clic en él y entra directamente en el curso.
- Usted consulta el estado en cualquier momento mediante GET /v1/users/{identifier}, o se lo notificamos a su servidor mediante un webhook.
Usted es el responsable del tratamiento del identificador; nosotros solo tratamos datos seudonimizados. Nunca envíe como identificador un correo electrónico ni un nombre - la API rechaza una dirección de correo electrónico con el error 422.
Dirección y autenticación
Cada llamada va por HTTPS a la dirección indicada abajo y lleva su clave API en la cabecera Authorization.
https://api.responsiblo.com Authorization: Bearer rsb_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- rsb_live_... abre su programa de producción, rsb_test_... su programa de prueba (sandbox).
- La clave se muestra solo una vez, al crearla; solo guardamos su huella. Guárdela como secreto en su servidor - nunca en un navegador ni en una aplicación.
- La clave tiene permisos: read (el estado y la lista de personas, el certificado) y write (el envío y la anonimización de personas). Puede estar limitada a sus direcciones IP y tener una validez.
- Renovación: usted crea una clave nueva, la antigua sigue siendo válida 7 días y después caduca.
- Las respuestas nunca se guardan en caché (Cache-Control: no-store) y la API no acepta llamadas desde un navegador (sin CORS).
POST /v1/users
Envía una persona al programa de la clave (permiso 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"}'
| Campo | Obligatorio | Significado |
|---|---|---|
identifier |
sí | Su seudónimo de la persona, de 1 a 64 caracteres A-Z a-z 0-9 . _ : @ -; nunca una dirección de correo electrónico (rechazada con 422). |
program |
no | Código del programa; si lo indica, debe ser el programa de la clave. |
language |
no | Idioma del curso (cs, en, ...); por defecto, el primer idioma del programa. |
label |
no | Su etiqueta - una cohorte o una campaña, de 1 a 64 caracteres, nunca un dato personal. |
expiresAt |
no | Último día de acceso, AAAA-MM-DD. |
201 Created para una persona nueva, 200 OK si el identificador ya existe - no cambia nada, la llamada se puede repetir con seguridad. El cuerpo es el estado descrito abajo, con entryUrl. Un límite agotado de personas o de licencias del programa devuelve 403.
GET /v1/users/{identifier}
Estado de una persona (permiso read): lo que necesita un control de cumplimiento normativo, nada más.
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/..."
}
status | Significado |
|---|---|
enrolled |
enviada, aún no ha entrado |
started |
ha entrado, todavía no ha completado nada |
in_progress |
tiene lecciones completadas, el programa todavía no |
completed |
el programa está completado (completedAt) |
expired |
el acceso ha terminado (ha pasado expiresAt; una persona del sandbox termina a los 7 días) |
quizScore es el resultado del cuestionario final en %, en cuanto se completa. Las horas están en UTC con segundos enteros. El campo certificate lleva el certificado de la persona (véase abajo); mientras no lo tenga, es null.
?include=detail
Añade el avance en cada curso y el resultado de cada cuestionario - nunca las respuestas individuales.
"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 de las personas que ha enviado al programa de la clave (permiso read), página por página: cada elemento tiene la forma del estado descrito arriba. Opcionalmente status (solo las personas en ese estado), limit (de 1 a 500, por defecto 100) y 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"
- Continúe con cursor = nextCursor mientras nextCursor no sea null; el cursor es un texto opaco, nunca lo construya usted mismo.
- Las personas van por el momento del envío, en un orden estable (también con el mismo momento), ninguna dos veces; las personas anonimizadas no aparecen en la lista.
- Con el filtro status recorremos como máximo 2000 personas por página, por lo que una página puede tener menos elementos que limit, incluso ninguno - continúe mientras haya un nextCursor.
Certificado de la persona
En cuanto la persona completa el programa, el curso le emite un certificado - con su seudónimo (el apodo del perfil ID XXXXXX), sin nombre y sin correo electrónico. No se envía nada por correo electrónico; el estado de la persona incluye el campo certificate con el número, las fechas y la página pública de verificación, y el PDF se descarga mediante 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
- La página de verificación verifyUrl muestra solo el seudónimo, el programa, el socio y la validez - nunca su identificador.
- El PDF devuelve application/pdf (permiso read). Sin certificado, la respuesta es 404 certificateNotFound; mientras el PDF aún se está generando, 404 certificatePdfNotReady con Retry-After.
- Un certificado revocado nunca se entrega (el campo certificate es entonces null, el PDF 404); un certificado con la validez vencida sigue siendo una prueba veraz y se entrega.
- Un webhook anuncia el certificado con el evento certificate.issued (justo después de user.completed).
DELETE /v1/users/{identifier}
Anonimiza a una persona (permiso write): del perfil desaparecen su identificador, la etiqueta y todo mensaje de webhook que lo mencione; los enlaces de acceso dejan de ser válidos. El certificado y el resultado del curso se conservan bajo el número del certificado - como prueba de cumplimiento normativo.
curl -X DELETE https://api.responsiblo.com/v1/users/client-48213 -H "Authorization: Bearer $RSB_KEY" HTTP/1.1 204 No Content
Respuesta 204 sin cuerpo; cada llamada posterior con el mismo identificador devuelve 404 userNotFound, por lo que repetirla es seguro. Después puede volver a enviar el mismo identificador como una persona nueva.
Enlace de acceso
Muestre entryUrl a la persona (un botón Iniciar el curso en su sistema). La inscribe en el curso - sin correo electrónico y sin contraseña.
El enlace es válido durante 30 días y se puede usar varias veces; cada llamada GET /v1/users/{identifier} devuelve uno nuevo. Nunca lo envíe a otra persona: quien tiene el enlace entra como esa persona.
Webhooks
En la pestaña API de su administración configura un webhook por programa: una dirección HTTPS pública de su servidor y los eventos. A partir de ahí le enviamos un POST con JSON - solo identificadores y estados, nunca el enlace de acceso.
| Evento | Cuándo |
|---|---|
user.enrolled |
la persona ha sido enviada (la primera vez que su webhook la conoce) |
user.started |
la persona ha entrado en el curso |
user.completed |
la persona ha completado el programa |
certificate.issued |
la persona ha obtenido un certificado; data incluye certificate (el número, las fechas, verifyUrl) |
user.expired |
el acceso de la persona ha terminado |
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
}
}
Firma
Cada mensaje lleva la cabecera X-Responsiblo-Signature: t=<tiempo Unix>,v1=<HMAC-SHA256 del texto t.cuerpo con el secreto del webhook, hex>. El secreto (whsec_...) se muestra una vez al crear el webhook. Antes de confiar en un mensaje, verifique la firma y la antigüedad de t; use X-Responsiblo-Delivery como clave de idempotencia.
// 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 y reintentos
Entregado = respuesta 2xx en 10 segundos. Si no, lo volvemos a intentar al cabo de 1 minuto, 5 minutos, 30 minutos, 2 horas y 12 horas, y después desistimos. No seguimos redirecciones.
20 mensajes no entregados seguidos desactivan el webhook hasta que usted lo vuelva a activar; los mensajes de ese periodo esperan. El botón Test envía un ping; el registro de entregas está en su administración.
El evento certificate.issued se añade a un webhook en su configuración; un webhook creado antes de la versión 1.2 no lo recibe por sí solo.
Errores
Cada error tiene una sola forma: status, code, reason y message; un error 422 añade errors (campo - qué está mal).
{ "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" } }
| HTTP | reason | Qué hacer |
|---|---|---|
| 400 | invalidJson |
envíe un único objeto JSON |
| 401 | missingToken, invalidToken |
envíe una clave válida (una clave revocada y una caducada tienen el mismo aspecto); la cabecera WWW-Authenticate indica Bearer |
| 403 | scopeDenied, ipNotAllowed, apiDisabled, partnerInactive, spaceUnavailable, httpsRequired, userLimitReached, seatsExhausted |
la clave no tiene permiso para esto, la API está desactivada para su empresa o el programa está lleno |
| 404 | userNotFound, notFound |
en el programa de la clave no hay ninguna persona con este identificador (tampoco anonimizada) |
| 404 | certificateNotFound, certificatePdfNotReady |
la persona aún no tiene certificado o su PDF se está generando - vuelva a intentarlo después de Retry-After |
| 409 | identifierTaken |
el identificador pertenece a una persona de otro programa |
| 422 | invalidBody, invalidParameter |
véase errors (un campo del cuerpo o un parámetro de la consulta - qué está mal) |
| 429 | rateLimited |
espere Retry-After segundos |
| 500 | internalError |
vuelva a intentarlo más tarde; indique incidentId a nuestro servicio de asistencia |
Para programas y agentes
- Decida según code y reason, nunca según el texto de message; errors es un objeto campo -> qué está mal.
- Repita solo 429, 500 y certificatePdfNotReady, y hágalo tras Retry-After segundos (si no, con un intervalo creciente); no repita otros 4xx distintos de 429 sin corregir la llamada.
- POST /v1/users es idempotente según identifier (201 la primera vez, después 200); DELETE devuelve 204 la primera vez y 404 después - ambas se pueden repetir con seguridad.
- Elimine duplicados de los webhooks según X-Responsiblo-Delivery; el orden de los mensajes no está garantizado, decide el estado en data.
Guía del préstamo
La guía del préstamo es un curso breve para la persona solicitante ante un prestamista: antes de firmar el contrato, recorre tres lecciones, ocho situaciones prácticas y, en su caso, un cuestionario, todo ello con las cifras de su propia oferta, y al final confirma la oferta. En cada pantalla puede pedir una explicación. Usted envía la oferta mediante la API, recibe un enlace de acceso y un webhook le notifica el resultado.
Activamos la guía del préstamo de común acuerdo con usted.
También aquí la persona solicitante es solo su perfil seudonimizado de POST /v1/users. La oferta se identifica por sus referencias (externalApplicationId, offerReference) y los documentos solo por un enlace con una huella SHA-256 - nunca un nombre, un correo electrónico, un número de identificación personal, un número de cuenta ni un teléfono. responsiblo no aprueba el préstamo, no descarga ni almacena los documentos, no verifica la identidad y no emite ningún certificado por la guía.
- Usted crea el perfil de la persona solicitante: POST /v1/users con su seudónimo.
- Usted envía la oferta: POST /v1/users/{identifier}/loan-offers; la respuesta 201 lleva entryUrl.
- Usted entrega entryUrl a la persona solicitante por su propio canal verificado. El enlace es válido durante 30 días y se puede usar varias veces; la guía muestra las cifras de su oferta.
- El final se lo comunica un webhook (loanGuide.completed, loanGuide.assistanceRequested y otros).
- Usted consulta el estado mediante GET …/loan-offers/{offerReference} y el registro para su expediente mediante GET …/evidence. Oferta modificada = nueva oferta con supersedes, solicitud retirada = POST …/cancel.
Hasta la activación, las operaciones de la guía responden 404 notFound o 409 loanGuideNotConfigured. El permiso write envía y cancela una oferta, read lee el estado y la prueba.
POST /v1/users/{identifier}/loan-offers
Envía una oferta al perfil de la persona solicitante (permiso write). La cabecera opcional Idempotency-Key tiene de 1 a 255 caracteres ASCII visibles. Ejemplo: préstamo de 10.000 CZK, 10.800 CZK a pagar en un solo pago 30 días después del desembolso, TAE 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"
}
| Campo | Obligatorio | Significado |
|---|---|---|
externalApplicationId |
sí | Su número de solicitud, de 1 a 128 caracteres A-Z a-z 0-9 . _ : -; nunca una dirección de correo electrónico. |
offerReference |
sí | Su referencia de la oferta, mismas reglas que externalApplicationId. |
locale |
sí | Idioma y país de la guía: cs-CZ. |
currency |
sí | Moneda: CZK. |
principalMinor |
sí | Importe del préstamo en haléř (céntimos de corona), número entero de 1 a 10.000.000.000. |
disbursedAmountMinor |
sí | Importe desembolsado en haléř; debe ser igual al importe del préstamo. |
totalPayableMinor |
sí | Importe total a pagar en haléř; como mínimo el importe del préstamo y exactamente la suma de los pagos. |
aprPercent |
sí | TAE en porcentaje como texto ("155.10"), calculada y garantizada por usted. La API rechaza costes positivos con una TAE de 0. |
interestRate |
no | Tipo de interés {percent, period}, period = year, month o day. |
repayment |
sí | Reembolso: singlePayment {amountMinor, due} con una fecha (kind date) o un número de días desde el desembolso (kind relative, de 1 a 365), o installments {schedule: [{date, amountMinor}]} con 1 a 360 cuotas en orden ascendente, ninguna en el pasado. El tipo debe corresponder al producto configurado para su guía. |
documents |
sí | De 2 a 10 documentos {role, reference, title, url, sha256}; cubiertos los roles que exige la configuración de su guía (por defecto precontract_information y contract_package). url solo HTTPS en un host permitido en la configuración de su guía, como máximo 2.048 caracteres, sin credenciales; sha256 = 64 caracteres hexadecimales que declara usted. |
validUntil |
sí | Validez de la oferta, RFC 3339 con desfase horario, en el futuro y como máximo 7 días por delante. |
supersedes |
no | offerReference de la oferta activa del mismo perfil que la nueva oferta sustituye. |
returnUrl |
no | Opcional: la dirección a la que la página «Terminado» devuelve al solicitante al final de la guía. Solo HTTPS absoluto, como máximo 2.048 caracteres, sin credenciales; sustituimos los símbolos {offerReference} y {externalApplicationId} por las referencias de la oferta. Sin ella se aplica la dirección de retorno de la configuración de su guía. |
El mismo cuerpo de nuevo (con las mismas referencias o la misma Idempotency-Key) devuelve 200 con la oferta existente y un entryUrl nuevo; otro cuerpo con ellas devuelve 409 offerConflict. Un perfil tiene una sola oferta activa: otra sin supersedes devuelve 409 activeOfferExists, un supersedes erróneo 409 notSupersedable. La configuración de su guía (cuestionario, contacto) queda en ese momento bloqueada para la oferta.
Estado, prueba y cancelación
GET /v1/users/{identifier}/loan-offers/{offerReference}- estado (permiso read): offerStatus (active, expired, superseded, cancelled), guideStatus (created, in_progress, completed), lecciones completadas, práctica, cuestionario (null si está desactivado) y los momentos de la presentación de la oferta, de la confirmación y de la solicitud de explicación. Nunca las respuestas, los valores de la oferta ni el enlace. La finalización se mantiene aunque la oferta caduque más tarde.GET /v1/users/{identifier}/loan-offers/{offerReference}/evidence- registro para su expediente (permiso read): schemaVersion loan-guide-evidence/1, instantánea de su oferta con la huella snapshotSha256, edición del curso con las huellas de las lecciones, eventos en el orden de sequence, cada respuesta con todos sus intentos, la confirmación y limitations - lo que el registro no prueba (presentado no significa leído, la identidad la afirma usted, los documentos solo por referencia, ningún certificado, ninguna aprobación del préstamo).POST /v1/users/{identifier}/loan-offers/{offerReference}/cancel- cancela una oferta activa (permiso write), reasonCode = withdrawn_by_provider o application_closed; 200 devuelve el estado, una oferta que no está activa o cuya guía está completada devuelve 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= solo es necesario cuando una offerReference pertenece a varias solicitudes del perfil (si no, 409 ambiguousOfferReference).
Webhooks de la guía
El webhook del programa (véase Webhooks) recibe los eventos de la guía sin suscripción aparte. La firma, la entrega y los reintentos son los mismos que en los demás eventos; data lleva identifier, offerReference, externalApplicationId, guideStatus, occurredAt y sequence (el orden de los eventos de una oferta) - nunca la prueba, los valores de la oferta ni el enlace de acceso.
| Evento | Cuándo |
|---|---|
loanGuide.completed |
la persona solicitante completó la guía y confirmó la oferta |
loanGuide.assistanceRequested |
la persona solicitante pidió una explicación (llámela) |
loanGuide.expired |
venció el validUntil de la oferta |
loanGuide.superseded |
una oferta nueva la sustituyó (supersedes) |
loanGuide.cancelled |
usted canceló la oferta |
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 llega a un mismo webhook como máximo una vez (clave de idempotencia = X-Responsiblo-Delivery). Un webhook creado más tarde no reproduce los eventos anteriores, y los eventos de más de 28 días ya no se notifican.
Conservación de la prueba
Cuando el recorrido de una oferta termina (oferta completada, cancelada, caducada o sustituida), corre el plazo de conservación de la configuración de su guía (30 días por defecto). Después la prueba se elimina: GET …/evidence devuelve 410 evidenceErased y el estado sigue respondiendo con evidenceErased: true, las referencias y los momentos. Una oferta activa nunca se elimina. Descargue la prueba que deba conservar justo después de loanGuide.completed.
Errores de la guía
Los errores tienen la forma de la API descrita arriba. Además, para la guía:
| HTTP | reason | Qué hacer |
|---|---|---|
| 404 | offerNotFound |
el perfil no tiene esa oferta (userNotFound = el perfil no existe) |
| 409 | offerConflict, activeOfferExists, notSupersedable |
las referencias o la Idempotency-Key ya pertenecen a otro cuerpo, o el perfil tiene otra oferta activa - envíe supersedes |
| 409 | loanGuideNotConfigured |
la guía no está activada para su programa - escríbanos |
| 409 | ambiguousOfferReference |
añada ?externalApplicationId= |
| 409 | notActive |
la oferta no está activa o su guía está completada |
| 410 | evidenceErased |
la prueba se eliminó tras el plazo de conservación, el estado se mantiene |
| 422 | invalidOffer |
errors = {ruta: código[,código]} con la ruta en el cuerpo (repayment.schedule[2].date, documents[0].url); los códigos en la tabla de abajo |
| 422 | invalidBody |
supersedes, Idempotency-Key o cuerpo de la cancelación |
errors | Códigos del error invalidOffer |
|---|---|
required |
falta el campo |
invalidFormat |
forma incorrecta (tipo, patrón, longitud, enlace sin HTTPS o con credenciales) |
outOfRange |
fuera del rango permitido (importe, número de documentos, de cuotas o de días) |
notEqualPrincipal |
el importe desembolsado no es igual al importe del préstamo |
sumMismatch |
la suma de los pagos no es igual al importe total a pagar |
belowPrincipal |
el importe total a pagar es inferior al importe del préstamo |
aprContradiction |
TAE 0 con costes positivos |
typeMismatch |
el tipo de reembolso no corresponde al producto configurado para su guía |
missingRole |
falta un documento con un rol que exige la configuración de su guía |
hostNotAllowed |
el enlace de un documento apunta a un host que la configuración de su guía no permite |
notAscending |
las fechas de las cuotas no van en orden ascendente o se repiten |
inPast |
la fecha de una cuota o validUntil está en el pasado |
tooFar |
validUntil está a más de 7 días en el futuro |
unsupported |
valor no admitido (locale, currency, type, period, kind) |
unknownField |
campo que la API no conoce |
looksLikeEmail |
una referencia parece una dirección de correo electrónico |
Un error nunca repite un valor que usted haya enviado. Ejemplo: la misma oferta con un pago de 10.700 CZK en lugar de 10.800 CZK y una validez de 9 días:
"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"
}
}
Límites
120 llamadas por minuto y clave. Tras 30 claves rechazadas desde una misma dirección en diez minutos, la dirección espera 10 minutos.
Conservamos el registro de llamadas (sin cuerpos, el identificador solo como huella SHA-256) durante 180 días, y los mensajes de webhook entregados y abandonados durante 30 días.
Estado y contrato
GET /v1/status- sin clave, devuelve {"status":"ok","version":"1.3.2"}GET /openapi- sin clave, el documento OpenAPI 3 de la API para socios
Sandbox
La clave de prueba rsb_test_... abre su programa de prueba con el mismo curso. Las personas en él terminan a los 7 días; el webhook del programa de prueba está separado del de producción.
Historial de versiones
- 1.3.2 (2026-11) - Cada operación del documento OpenAPI tiene un nombre y una descripción, y las operaciones están organizadas en grupos. /v1/status y los webhooks indican la versión 1.3.2. La forma de las solicitudes y las respuestas no cambia.
- 1.3.1 (2026-10) - Correcciones sin cambios en los endpoints ni en sus respuestas.
- 1.3.0 (2026-10) - Guía del préstamo: POST /v1/users/{identifier}/loan-offers, estado, prueba y cancelación de una oferta, webhooks loanGuide.*, conservación de la prueba. Campo opcional returnUrl de una oferta (dirección de retorno propia).
- 1.2.0 (2026-10) - GET /v1/users con paginación, el certificado de la persona (campo certificate, GET /v1/users/{identifier}/certificate, evento certificate.issued), DELETE /v1/users/{identifier} (anonimización), identificador de 64 caracteres como máximo, conservación del registro.
- 1.1.0 (2026-10) - Claves API, POST /v1/users, GET /v1/users/{identifier} con ?include=detail, enlace de acceso, webhooks, una sola forma de errores, estado público y OpenAPI, límites.
- 1.0.0 (2024) - GET /v1/user/{identifier} con el JWT de la clave de socio.
¿Quiere la API para su empresa? Escríbanos