Saltar al contenido principal

POST /credentials/issue

Emite credenciales a uno o multiples recipientes.

  • 1 recipiente: Emision sincrona. Retorna la credencial inmediatamente.
  • 2+ recipientes: Emision asincrona. Retorna un job_id para consultar el progreso.

Request

POST /api/v1/credentials/issue

Headers

HeaderRequeridoDescripcion
X-API-KeySiTu API key
Content-TypeSiapplication/json

Body

{
"template_id": "550e8400-e29b-41d4-a716-446655440000",
"recipients": [
{
"email": "estudiante@ejemplo.com",
"recipient_name": "Juan Perez",
"result_value": "A",
"credits_earned": 6.0
}
]
}

Campos del recipiente

CampoTipoRequeridoDescripcion
emailstringSiempreEmail del recipiente
recipient_namestringSegun templateNombre completo
result_valuestringSegun templateCalificacion/resultado
credits_earnednumberSegun templateCreditos obtenidos
evidencearraySegun templateEvidencia del trabajo
rolestringSegun templateRol del recipiente
license_numberstringSegun templateNumero de licencia
termstringSegun templatePeriodo academico
activity_start_datestringSegun templateFecha inicio (YYYY-MM-DD)
activity_end_datestringSegun templateFecha fin (YYYY-MM-DD)

Estructura de evidence

{
"evidence": [
{
"name": "Proyecto Final",
"url": "https://ejemplo.com/proyecto",
"description": "Implementacion de API REST en Python"
}
]
}

Consulta GET /templates/\{id\} para saber que campos son requeridos por cada template.

Response: Emision sincrona (1 recipiente)

{
"mode": "sync",
"credentials": [
{
"email": "estudiante@ejemplo.com",
"status": "issued",
"credential_id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d",
"credential_url": "https://app.unicreda.com/credential/7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d"
}
]
}

Response: Emision asincrona (2+ recipientes)

{
"mode": "async",
"job_id": "abc123-task-id",
"message": "Issuing 50 credentials in background. Poll GET /api/v1/jobs/abc123-task-id for status."
}

Usa GET /jobs/\{job_id\} para consultar el progreso.

Deteccion automatica interno/externo

La API detecta automaticamente si el email corresponde a un miembro de tu organizacion:

  • Interno: Se enlazan automaticamente al wallet del usuario + se auto-llenan campos del perfil
  • Externo: Se crea la credencial y se envia por email con un enlace publico

Errores por recipiente

Si un recipiente tiene datos invalidos en modo sincrono:

{
"mode": "sync",
"credentials": [
{
"email": "estudiante@ejemplo.com",
"status": "error",
"errors": ["Calificacion invalida. Valores permitidos: A, B, C, D, F"]
}
]
}

Ejemplo: Emision masiva con Python

import requests
import time

API_KEY = "uc_live_tu_key_aqui"
BASE_URL = "https://app.unicreda.com/api/v1"
headers = {"X-API-Key": API_KEY, "Content-Type": "application/json"}

# Emitir a multiples recipientes
response = requests.post(f"{BASE_URL}/credentials/issue", headers=headers, json={
"template_id": "550e8400-e29b-41d4-a716-446655440000",
"recipients": [
{"email": f"estudiante{i}@ejemplo.com", "recipient_name": f"Estudiante {i}", "result_value": "A"}
for i in range(1, 51)
]
})

data = response.json()
if data["mode"] == "async":
job_id = data["job_id"]

# Polling del progreso
while True:
status = requests.get(f"{BASE_URL}/jobs/{job_id}", headers=headers).json()
print(f"Status: {status['status']}")

if status["status"] == "SUCCESS":
print(f"Resultado: {status['result']}")
break
elif status["status"] == "FAILURE":
print(f"Error: {status['error']}")
break

time.sleep(2) # Esperar 2 segundos entre consultas