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.
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.
| ScopePermiso | GrantsPermite |
|---|---|
| events:read, events:write | Read, or create / update / delete, events and their registration settingsLeer, o crear / actualizar / eliminar, eventos y su configuración de registro |
| attendees:read, attendees:write | Read, or create / update / delete / import, attendeesLeer, o crear / actualizar / eliminar / importar, asistentes |
| templates:read, templates:write | Read, or manage, certificate templatesLeer, o administrar, plantillas de certificados |
| certificates:generate | Issue, regenerate and bulk-generate certificatesEmitir, regenerar y generar certificados de forma masiva |
| certificates:read, certificates:write | Read and download certificates, or revoke, delete and send themLeer y descargar certificados, o revocarlos, eliminarlos y enviarlos |
| badges:read, badges:write | Read, or create / update / delete / issue, badgesLeer, o crear / actualizar / eliminar / emitir, insignias |
| analytics:read | Dashboard and per-event analyticsAnalítica del panel y por evento |
| webhooks:manage | Manage webhook subscriptions and read their deliveriesAdministrar suscripciones de webhooks y consultar sus entregas |
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.
Every path below is relative to /api/v1.Todas las rutas siguientes son relativas a /api/v1.
| AreaÁrea | EndpointsEndpoints |
|---|---|
| EventsEventos | GET/POST /events GET/PUT/DELETE /events/{id} GET /events/{id}/attendees GET /events/{id}/certificates GET/PUT /events/{id}/registration |
| Bulk issuingEmisión masiva | POST /events/{id}/certificates/generate POST /events/{id}/certificates/generate/jobs GET /events/{id}/certificates/generate/jobs/{jobId} |
| AttendeesAsistentes | GET/POST /attendees GET/PUT/DELETE /attendees/{id} GET /attendees/count POST /attendees/import GET /events/{id}/attendees/export |
| TemplatesPlantillas | GET/POST /templates GET/PUT/DELETE /templates/{id} POST /templates/{id}/duplicate POST /templates/{id}/preview GET /system-templates |
| CertificatesCertificados | POST /certificates/generate GET/DELETE /certificates/{id} GET /certificates/{id}/download POST /certificates/{id}/regenerate POST /certificates/{id}/revoke POST /certificates/{id}/send |
| BadgesInsignias | GET/POST /badges GET/PUT/DELETE /badges/{id} POST /badges/{id}/issue GET /badges/{id}/assertions |
| EmailCorreo | POST /email/send-bulk GET /email/deliveries |
| AnalyticsAnalítica | GET /analytics/dashboard GET /analytics/events/{id} |
| CreditsCréditos | GET /credits (credits used, limit and remaining this month)(créditos usados, límite y restantes este mes) |
| Webhooks | GET/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 |
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.
| EventEvento | Sent whenSe envía cuando |
|---|---|
| certificate.issued | A certificate is generated, one at a time or in bulkSe genera un certificado, individualmente o de forma masiva |
| certificate.sent | A certificate is emailed to its recipientSe envía un certificado por correo a su destinatario |
| certificate.viewed | The recipient opens their portal link for the first timeEl destinatario abre su enlace del portal por primera vez |
| certificate.downloaded | The recipient downloads the certificate PDF from the portalEl destinatario descarga el PDF del certificado desde el portal |
| certificate.revoked | You 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.
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.
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.