How It WorksCómo Funciona SolutionsSoluciones PricingPrecios ClientsClientes FAQ VerifyVerificar
Sign InIniciar Sesión Start FreeComenzar Gratis
DevelopersDesarrolladores

Issue and verify from your own systemsEmita y verifique desde sus propios sistemas

A JSON REST API with scoped API keys, plus signed webhooks that tell your systems what happened to each certificate. API access is included on every plan, including the free Starter plan. Una API REST con JSON y claves API con permisos limitados, además de webhooks firmados que informan a sus sistemas lo que ocurre con cada certificado. El acceso a la API está incluido en todos los planes, incluido el plan gratuito Starter.

AuthenticationAutenticación

Create an API key in the app under Settings, then API keys. Choose the scopes it needs and, optionally, an expiry in days. The full key (it starts with crtfd_live_) is shown once, so store it safely. Send it as a bearer token: Cree una clave API en la aplicación, en Configuración y luego Claves API. Elija los permisos que necesita y, si lo desea, una caducidad en días. La clave completa (empieza con crtfd_live_) se muestra una sola vez, así que guárdela en un lugar seguro. Envíela como token bearer:

Authorization: Bearer crtfd_live_your_key_here

All endpoints live under https://certifyd.cloud/api/v1 and speak JSON. Successful responses wrap the payload as { "data": ... }. Errors come back as { "error": { "code", "message" } }. Common codes are INVALID_API_KEY, INSUFFICIENT_SCOPE (the response names the missing scope) and CREDIT_LIMIT (HTTP 402, your monthly credits are used up). Requests are rate limited. Back off when you receive HTTP 429. Todos los endpoints están bajo https://certifyd.cloud/api/v1 y usan JSON. Las respuestas correctas envuelven el contenido como { "data": ... }. Los errores llegan como { "error": { "code", "message" } }. Los códigos comunes son INVALID_API_KEY, INSUFFICIENT_SCOPE (la respuesta indica el permiso que falta) y CREDIT_LIMIT (HTTP 402, ya usó sus créditos mensuales). Las solicitudes tienen límite de frecuencia. Espere antes de reintentar si recibe HTTP 429.

ScopesPermisos

ScopePermisoGrantsPermite
events:read, events:writeRead, or create / update / delete, events and their registration settingsLeer, o crear / actualizar / eliminar, eventos y su configuración de registro
attendees:read, attendees:writeRead, or create / update / delete / import, attendeesLeer, o crear / actualizar / eliminar / importar, asistentes
templates:read, templates:writeRead, or manage, certificate templatesLeer, o administrar, plantillas de certificados
certificates:generateIssue, regenerate and bulk-generate certificatesEmitir, regenerar y generar certificados de forma masiva
certificates:read, certificates:writeRead and download certificates, or revoke, delete and send themLeer y descargar certificados, o revocarlos, eliminarlos y enviarlos
badges:read, badges:writeRead, or create / update / delete / issue, badgesLeer, o crear / actualizar / eliminar / emitir, insignias
analytics:readDashboard and per-event analyticsAnalítica del panel y por evento
webhooks:manageManage webhook subscriptions and read their deliveriesAdministrar suscripciones de webhooks y consultar sus entregas
API keys cannot create or revoke other API keys: that is only possible from a signed-in session in the app, so a leaked key cannot mint a replacement for itself. Las claves API no pueden crear ni revocar otras claves API: eso solo es posible desde una sesión iniciada en la aplicación, de modo que una clave filtrada no pueda generarse un reemplazo.

Example: issue a certificate, then verify itEjemplo: emitir un certificado y verificarlo

The key needs the scopes templates:read, events:write, attendees:write and certificates:generate. Each issued certificate uses one credit. The examples use jq to pick values out of the JSON. La clave necesita los permisos templates:read, events:write, attendees:write y certificates:generate. Cada certificado emitido usa un crédito. Los ejemplos usan jq para extraer valores del JSON.

# 0. Your key and the API address
export CERTIFYD_KEY="crtfd_live_your_key_here"
export API="https://certifyd.cloud/api/v1"

# 1. Pick one of your templates (take the "id" of any entry in data)
curl -s "$API/templates?active=true" \
  -H "Authorization: Bearer $CERTIFYD_KEY" | jq '.data[] | {id, name}'
export TEMPLATE_ID="paste-a-template-id-here"

# 2. Create an event
export EVENT_ID=$(curl -s -X POST "$API/events" \
  -H "Authorization: Bearer $CERTIFYD_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"name\":\"Safety Training\",\"eventDate\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"templateId\":\"$TEMPLATE_ID\"}" \
  | jq -r '.data.id')

# 3. Add an attendee
export ATTENDEE_ID=$(curl -s -X POST "$API/attendees" \
  -H "Authorization: Bearer $CERTIFYD_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"eventId\":\"$EVENT_ID\",\"firstName\":\"Ana\",\"lastName\":\"Rivera\",\"email\":\"ana@example.com\"}" \
  | jq -r '.data.id')

# 4. Issue the certificate ("sendEmail": false holds back the delivery email)
export CODE=$(curl -s -X POST "$API/certificates/generate" \
  -H "Authorization: Bearer $CERTIFYD_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"templateId\":\"$TEMPLATE_ID\",\"eventId\":\"$EVENT_ID\",\"attendeeId\":\"$ATTENDEE_ID\",\"sendEmail\":false}" \
  | jq -r '.data.verificationCode')
echo "Verification code: $CODE"

# 5. Verify it. This endpoint is public: no API key needed.
curl -s "$API/verify/$CODE"

The verify response includes status (valid, expired or revoked), the recipient, the credential, the issuer and the dates. The same code opens the human-readable page at https://certifyd.cloud/verify/<code>. See how to verify a credential. La respuesta de verificación incluye status (valid, expired o revoked), el destinatario, la credencial, el emisor y las fechas. El mismo código abre la página legible en https://certifyd.cloud/verify/<code>. Consulte cómo verificar una credencial.

EndpointsEndpoints

Every path below is relative to /api/v1.Todas las rutas siguientes son relativas a /api/v1.

AreaÁreaEndpointsEndpoints
EventsEventosGET/POST /events GET/PUT/DELETE /events/{id} GET /events/{id}/attendees GET /events/{id}/certificates GET/PUT /events/{id}/registration
Bulk issuingEmisión masivaPOST /events/{id}/certificates/generate POST /events/{id}/certificates/generate/jobs GET /events/{id}/certificates/generate/jobs/{jobId}
AttendeesAsistentesGET/POST /attendees GET/PUT/DELETE /attendees/{id} GET /attendees/count POST /attendees/import GET /events/{id}/attendees/export
TemplatesPlantillasGET/POST /templates GET/PUT/DELETE /templates/{id} POST /templates/{id}/duplicate POST /templates/{id}/preview GET /system-templates
CertificatesCertificadosPOST /certificates/generate GET/DELETE /certificates/{id} GET /certificates/{id}/download POST /certificates/{id}/regenerate POST /certificates/{id}/revoke POST /certificates/{id}/send
BadgesInsigniasGET/POST /badges GET/PUT/DELETE /badges/{id} POST /badges/{id}/issue GET /badges/{id}/assertions
EmailCorreoPOST /email/send-bulk GET /email/deliveries
AnalyticsAnalíticaGET /analytics/dashboard GET /analytics/events/{id}
CreditsCréditosGET /credits (credits used, limit and remaining this month)(créditos usados, límite y restantes este mes)
WebhooksGET/POST /webhooks PUT/DELETE /webhooks/{id} GET /webhooks/{id}/deliveries POST /webhooks/{id}/test
Verification (public)Verificación (pública)GET /verify/{code} GET /verify/{code}/qr GET /verify/{code}/preview.png GET /verify/{code}/badge.png GET /verify/{code}/badge.svg GET /verify/{code}/certificate.pdf

Webhooks

Subscribe an HTTPS endpoint with POST /webhooks (or in the app under Settings, then Webhooks), choosing which events it receives. Endpoints must use HTTPS and resolve to a public address. The signing secret is returned once, when the subscription is created. Suscriba un endpoint HTTPS con POST /webhooks (o en la aplicación, en Configuración y luego Webhooks) y elija los eventos que recibirá. Los endpoints deben usar HTTPS y resolver a una dirección pública. El secreto de firma se devuelve una sola vez, al crear la suscripción.

EventEventoSent whenSe envía cuando
certificate.issuedA certificate is generated, one at a time or in bulkSe genera un certificado, individualmente o de forma masiva
certificate.sentA certificate is emailed to its recipientSe envía un certificado por correo a su destinatario
certificate.viewedThe recipient opens their portal link for the first timeEl destinatario abre su enlace del portal por primera vez
certificate.downloadedThe recipient downloads the certificate PDF from the portalEl destinatario descarga el PDF del certificado desde el portal
certificate.revokedYou revoke a certificateUsted revoca un certificado

You can also send yourself a sample with POST /webhooks/{id}/test, which delivers a webhook.test event. También puede enviarse una muestra con POST /webhooks/{id}/test, que entrega un evento webhook.test.

What you receiveQué recibe

POST https://your-server.example/certifyd-hook
Content-Type: application/json
X-Certifyd-Event: certificate.issued
X-Certifyd-Delivery: 7c0e5b0e-0000-0000-0000-000000000000
X-Certifyd-Timestamp: 1790000000
X-Certifyd-Signature: sha256=3f1c...e9

{ "eventType": "certificate.issued", "timestamp": "...", "data": { "certificateId": "...", "certificateNumber": "...", "eventId": "...", "attendeeId": "...", "status": "...", "verificationCode": "CFD-7X4K-92QM" } }

The signature is a hex HMAC-SHA256 of "{timestamp}.{raw body}" keyed with your subscription secret. Verify it, reject timestamps that are more than a few minutes old, and use X-Certifyd-Delivery to ignore duplicates. It stays the same across retries. La firma es un HMAC-SHA256 en hexadecimal de "{timestamp}.{cuerpo sin modificar}" con el secreto de su suscripción como clave. Verifíquela, rechace marcas de tiempo con más de unos minutos de antigüedad y use X-Certifyd-Delivery para ignorar duplicados. No cambia entre reintentos.

# Recompute the signature on your side (bash + openssl)
printf '%s.%s' "$TIMESTAMP" "$RAW_BODY" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET"

Each delivery times out after 10 seconds. A failed delivery is tried up to 5 times in total, after 1 minute, 5 minutes, 30 minutes and 2 hours. A subscription that keeps failing is switched off after 10 failed attempts in a row. Cada entrega tiene un tiempo límite de 10 segundos. Una entrega fallida se intenta hasta 5 veces en total, tras 1 minuto, 5 minutos, 30 minutos y 2 horas. Una suscripción que sigue fallando se desactiva tras 10 intentos fallidos seguidos.

What is not availableLo que no está disponible

There are no official client libraries and no published OpenAPI document yet. There is no native Zapier or Make connector either: any tool that can send HTTPS requests and receive webhooks can integrate with the endpoints above. Todavía no hay bibliotecas cliente oficiales ni un documento OpenAPI publicado. Tampoco hay un conector nativo de Zapier o Make: cualquier herramienta que pueda enviar solicitudes HTTPS y recibir webhooks puede integrarse con los endpoints anteriores.

Get your API keyObtenga su clave API Create a free account, then add a key under Settings, API keys.Cree una cuenta gratuita y luego agregue una clave en Configuración, Claves API.
Start FreeComenzar Gratis