API Direct Issuance¶
Emite credenciales programáticamente desde tu backend, sin pasar por la UI del Portal Issuer. Útil para integraciones masivas o automatizaciones por evento.
¿Cuándo usar esta guía?
- Tu sistema ya sabe cuándo debe emitir una credencial (alta de empleado, finalización de un curso, etc.).
- No quieres que un humano entre al Portal Issuer cada vez.
- Necesitas emitir en lote o desde un flujo automatizado (CI, webhooks, ETL).
Flujo resumido¶
- Autentícate contra el Issuer usando OAuth 2.0 client credentials (M2M).
- Crea la oferta con
POST /issuer/api/v1/issuances. - Entrega la
credential_offer_urial destinatario (email, QR, push). - Opcional: suscríbete a webhooks para recibir notificaciones de estado.
Paso 1: Autenticación M2M¶
El Issuer autentica sistemas backend mediante OAuth 2.0 Client Credentials. Las credenciales (client_id y client_secret) se obtienen al aprovisionar el tenant.
Token request / response
Paso 2: Crear la oferta de credencial¶
Con el access_token obtenido, crea la oferta. El campo client_request_id garantiza idempotencia: si repites la llamada con el mismo valor, el Issuer devuelve la misma oferta sin crear un duplicado.
Crear oferta — request / body / response
{
"client_request_id": "onboarding-2026-05-18-emp-00342",
"credential_configuration_id": "learcredential.employee.sd.1",
"payload": {
"mandator": {
"organizationIdentifier": "VATES-12345678A",
"organization": "EUDIStack Demo",
"commonName": "Admin User",
"email": "admin@eudistack.com",
"country": "ES"
},
"mandatee": {
"firstName": "Ana",
"lastName": "García",
"email": "ana.garcia@eudistack.com"
},
"power": [
{ "function": "Admin", "action": ["Execute"] }
]
},
"delivery": "email",
"email": "ana.garcia@eudistack.com",
"grant_type": "urn:ietf:params:oauth:grant-type:pre-authorized_code"
}
{
"issuance_id": "a3f1b2c4-7d8e-9f0a-b1c2-d3e4f5a6b7c8",
"credential_offer_uri": "openid-credential-offer://?credential_offer_uri=https://sandbox-stg.eudistack.net/issuer/oid4vci/v1/credential-offer/XXXX",
"status": "pending",
"expires_at": "2026-05-18T18:00:00Z"
}
| Campo | Descripción |
|---|---|
issuance_id | Identificador interno. Úsalo para consultar estado o correlacionar webhooks. |
credential_offer_uri | URL o deep link que debes entregar al destinatario. |
status | Estado inicial: pending (el destinatario aún no ha aceptado). |
expires_at | Fecha de expiración del código preautorizado. |
Paso 3: Entregar la oferta al destinatario¶
Incluye el credential_offer_uri como enlace, o genera un QR y adjúntalo al email.
Envía el deep link openid-credential-offer://... directamente a la app del usuario.
Genera el QR en tiempo real en tu aplicación web cuando el usuario esté presente.
(Opcional) Paso 4: Webhooks de estado¶
Registra un endpoint HTTPS en la configuración del tenant para recibir notificaciones de cambio de estado.
Eventos disponibles
| Evento | Descripción |
|---|---|
issuance.accepted | El destinatario aceptó la credencial en su wallet. |
issuance.rejected | El destinatario rechazó la oferta o caducó sin ser aceptada. |
issuance.error | Error durante la emisión (plantilla no encontrada, datos inválidos, etc.). |
Payload de ejemplo
Buenas prácticas
- Idempotencia: incluye un
client_request_idúnico por oferta para evitar duplicados si tu sistema reintenta. - Retries: usa backoff exponencial — los endpoints son idempotentes con el mismo
client_request_id. - Privacidad: no almacenes los atributos de la credencial en tu sistema más tiempo del necesario.
- Expiración: supervisa el campo
expires_at; si la oferta caduca sin ser aceptada, crea una nueva.