Docs/API y webhooks/Certificados

Certificados

SecureCodingHub emite automáticamente un certificado cuando un usuario completa cada escenario de aprendizaje y cada reto de práctica en una categoría entera (Web, API, Móvil, Cliente). Estos endpoints exponen los certificados emitidos y una consulta de verificación de estilo público. Requiere el scope certificates:read.

Endpoints

MétodoRutaScopePropósito
GET/certificates/users/{'{'}userId{'}'}certificates:readEstado de los certificados de cada categoría, para un único usuario.
GET/certificates/verify/{'{'}certNumber{'}'}certificates:readVerificar un certificado por su número público.

Todas las rutas son relativas a https://api.limeplate.com/api/public/v1.

Cómo se emiten los certificados

La emisión es totalmente automática: no hay un endpoint manual de "conceder". Las reglas:

  • Un certificado por categoría y por usuario. Las categorías son web, api, mobile y client.
  • Un certificado de categoría se emite en el momento en que un usuario completa todos los escenarios de aprendizaje y todos los retos de práctica de esa categoría.
  • A cada certificado se le asigna un certificateNumber permanente y compartible públicamente.
  • La emisión dispara un evento de webhook certificate.issued. Consulta Webhooks para el payload.

Volver a completar contenido tras la emisión no genera un certificado nuevo; el número original es permanente.

Listar el estado de los certificados para un usuario

Devuelve una entrada por categoría. Las entradas en las que certificateId es null representan categorías que el usuario ha empezado pero aún no ha terminado: útiles para renderizar una UI tipo "te faltan 18 de 22 retos para tu certificado de Web".

GET /api/public/v1/certificates/users/{userId}
Authorization: Bearer scs_live_…

Respuesta

[
  {
    "categoryId": "web",
    "categoryTitle": "Web Application Security",
    "certificateId": "7e4c9d09-86ca-4125-bbd8-7fae54c8f654",
    "certificateNumber": "SCH-2026-WEB-000123",
    "issuedAt": "2026-05-12T08:41:22Z",
    "practiceTotal": 75,
    "practiceCompleted": 75,
    "learnTotal": 22,
    "learnCompleted": 22,
    "isComplete": true
  },
  {
    "categoryId": "api",
    "categoryTitle": "API Security",
    "certificateId": null,
    "certificateNumber": null,
    "issuedAt": null,
    "practiceTotal": 60,
    "practiceCompleted": 42,
    "learnTotal": 18,
    "learnCompleted": 14,
    "isComplete": false
  },
  {
    "categoryId": "mobile",
    "categoryTitle": "Mobile Application Security",
    "certificateId": null,
    "certificateNumber": null,
    "issuedAt": null,
    "practiceTotal": 50,
    "practiceCompleted": 0,
    "learnTotal": 15,
    "learnCompleted": 0,
    "isComplete": false
  },
  {
    "categoryId": "client",
    "categoryTitle": "Client-Side Security",
    "certificateId": null,
    "certificateNumber": null,
    "issuedAt": null,
    "practiceTotal": 40,
    "practiceCompleted": 6,
    "learnTotal": 12,
    "learnCompleted": 2,
    "isComplete": false
  }
]
  • isComplete refleja "practiceCompleted == practiceTotal && learnCompleted == learnTotal".
  • practiceTotal y learnTotal son recuentos en vivo: añadir nuevo contenido a una categoría no invalida los certificados ya emitidos, pero hará subir los denominadores de un usuario en curso.

Ejemplo

curl -sS \
  -H "Authorization: Bearer $SCH_API_KEY" \
  https://api.limeplate.com/api/public/v1/certificates/users/1a2b3c4d-5e6f-7081-9203-4d5e6f708192

Verificar un certificado

Busca un certificado por su número público y devuelve el titular, la organización y la categoría. Úsalo para respaldar una página "Verifica tu certificado" en tu sitio profesional, o para validar la afirmación de un candidato durante la contratación.

GET /api/public/v1/certificates/verify/{certNumber}
Authorization: Bearer scs_live_…

Aunque el endpoint se comporta como una consulta de verificación pública, sigue siendo obligatorio aportar la API key y el scope certificates:read al llamarlo. Si quieres verificación verdaderamente pública sin autenticación, enlaza a la URL de verificación alojada por SecureCodingHub: https://www.securecodinghub.com/verify/{'{'}certNumber{'}'}.

Respuesta

{
  "certificateNumber": "SCH-2026-WEB-000123",
  "userName": "Jane Smith",
  "organizationName": "Acme Corp",
  "categoryId": "web",
  "categoryTitle": "Web Application Security",
  "issuedAt": "2026-05-12T08:41:22Z"
}

Devuelve 404 certificate_not_found si no existe ningún certificado con ese número. Los certificados revocados o de fixture de prueba también devuelven 404.

Ejemplo

curl -sS \
  -H "Authorization: Bearer $SCH_API_KEY" \
  https://api.limeplate.com/api/public/v1/certificates/verify/SCH-2026-WEB-000123

Recibir eventos de certificado

Si quieres empujar los certificados hacia un sistema de RR. HH. o talento en el momento en que se emiten —en vez de hacer polling sobre el endpoint de usuario—, suscríbete al webhook certificate.issued. El payload del webhook incluye userId, certificateNumber, categoryId e issuedAt, replicando la respuesta de verificación. Consulta Webhooks.