Certificates
Certificates endpoints of the Zanfia Workspace API, with schemas and code samples.
Course-completion certificates and the templates they are rendered from. Issuing is asynchronous: POST /certificates/issue validates the batch, skips clients who already hold a certificate, and enqueues one issuance task per client — PDF rendering and the delivery email happen in the background, so the call answers 202 with counts only. Poll GET /certificates?productId=… until the client's row appears. A single issuance is the same call with one clientId. Certificates are addressed by their public credential id (cert_…); revoke is reversible via reinstate. All routes require a Authorization: Bearer header — see Authentication.
List certificates
/certificatesAuthorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Query Parameters
Course product id — omit for all courses.
1 <= lengthMax rows, newest first (max 500; the service default applies when omitted).
0 < value <= 500Response Body
application/json
application/json
curl -X GET "https://example.com/certificates"{ "certificates": [ { "id": "string", "certificateId": "string", "workspaceId": "string", "productId": "string", "courseId": "string", "clientId": "string", "recipientName": "string", "recipientEmail": "string", "courseName": "string", "issuerName": "string", "completionDate": "string", "issuedAt": "string", "issuedBy": "manual", "templateId": "string", "templateVersion": 0, "certificateHash": "string", "pdfStoragePath": "string", "pdfPublicUrl": "string", "verificationUrl": "string", "status": "active", "revokedAt": "string", "expiresAt": "string", "engagement": { "emailStatus": "submitted", "emailStatusAt": "string", "firstViewedAt": "string", "lastViewedAt": "string", "viewCount": 0, "downloadedAt": "string", "linkedInAddedAt": "string" } } ]}{ "error": "string", "message": "string"}Issue certificates (async)
/certificates/issueAuthorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
curl -X POST "https://example.com/certificates/issue" \ -H "Content-Type: application/json" \ -d '{ "productId": "string", "clientIds": [ "string" ] }'{ "enqueued": 0, "skippedExistingCertificate": 0}{ "error": "string", "message": "string"}List certificate templates
/certificates/templatesAuthorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Response Body
application/json
application/json
curl -X GET "https://example.com/certificates/templates"{ "templates": [ { "id": "string", "workspaceId": "string", "name": "string", "version": 0, "template": { "basePdf": null, "schemas": [ null ] }, "isDefault": true, "designConfig": { "preset": "elegant", "accentColor": "string", "typeface": "serif", "locale": "en", "wording": { "title": "string", "presentedToLabel": "string", "completedLabel": "string", "issuedByLabel": "string" }, "signature": { "enabled": true, "name": "string" }, "elements": { "logo": true, "completionDate": true, "credentialId": true, "verificationQr": true, "customText": true }, "logo": { "dataUri": "string", "width": 0, "height": 0, "size": "sm" } }, "createdAt": "string", "updatedAt": "string" } ]}{ "error": "string", "message": "string"}Create a certificate template
/certificates/templatesAuthorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
curl -X POST "https://example.com/certificates/templates" \ -H "Content-Type: application/json" \ -d '{ "name": "string" }'{ "template": { "id": "string", "workspaceId": "string", "name": "string", "version": 0, "template": { "basePdf": null, "schemas": [ null ] }, "isDefault": true, "designConfig": { "preset": "elegant", "accentColor": "string", "typeface": "serif", "locale": "en", "wording": { "title": "string", "presentedToLabel": "string", "completedLabel": "string", "issuedByLabel": "string" }, "signature": { "enabled": true, "name": "string" }, "elements": { "logo": true, "completionDate": true, "credentialId": true, "verificationQr": true, "customText": true }, "logo": { "dataUri": "string", "width": 0, "height": 0, "size": "sm" } }, "createdAt": "string", "updatedAt": "string" }}{ "error": "string", "message": "string"}Certificate template detail
/certificates/templates/{templateId}Authorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Path Parameters
Response Body
application/json
application/json
curl -X GET "https://example.com/certificates/templates/string"{ "template": { "id": "string", "workspaceId": "string", "name": "string", "version": 0, "template": { "basePdf": null, "schemas": [ null ] }, "isDefault": true, "designConfig": { "preset": "elegant", "accentColor": "string", "typeface": "serif", "locale": "en", "wording": { "title": "string", "presentedToLabel": "string", "completedLabel": "string", "issuedByLabel": "string" }, "signature": { "enabled": true, "name": "string" }, "elements": { "logo": true, "completionDate": true, "credentialId": true, "verificationQr": true, "customText": true }, "logo": { "dataUri": "string", "width": 0, "height": 0, "size": "sm" } }, "createdAt": "string", "updatedAt": "string" }}{ "error": "string", "message": "string"}Update a certificate template
/certificates/templates/{templateId}Authorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Path Parameters
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
curl -X PATCH "https://example.com/certificates/templates/string" \ -H "Content-Type: application/json" \ -d '{}'{ "template": { "id": "string", "workspaceId": "string", "name": "string", "version": 0, "template": { "basePdf": null, "schemas": [ null ] }, "isDefault": true, "designConfig": { "preset": "elegant", "accentColor": "string", "typeface": "serif", "locale": "en", "wording": { "title": "string", "presentedToLabel": "string", "completedLabel": "string", "issuedByLabel": "string" }, "signature": { "enabled": true, "name": "string" }, "elements": { "logo": true, "completionDate": true, "credentialId": true, "verificationQr": true, "customText": true }, "logo": { "dataUri": "string", "width": 0, "height": 0, "size": "sm" } }, "createdAt": "string", "updatedAt": "string" }}{ "error": "string", "message": "string"}Delete a certificate template
/certificates/templates/{templateId}Authorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Path Parameters
Response Body
application/json
application/json
curl -X DELETE "https://example.com/certificates/templates/string"{ "deleted": true}{ "error": "string", "message": "string"}Revoke a certificate
/certificates/{certificateId}/revokeAuthorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Path Parameters
Response Body
application/json
application/json
curl -X POST "https://example.com/certificates/string/revoke"{ "certificate": { "id": "string", "certificateId": "string", "workspaceId": "string", "productId": "string", "courseId": "string", "clientId": "string", "recipientName": "string", "recipientEmail": "string", "courseName": "string", "issuerName": "string", "completionDate": "string", "issuedAt": "string", "issuedBy": "manual", "templateId": "string", "templateVersion": 0, "certificateHash": "string", "pdfStoragePath": "string", "pdfPublicUrl": "string", "verificationUrl": "string", "status": "active", "revokedAt": "string", "expiresAt": "string", "engagement": { "emailStatus": "submitted", "emailStatusAt": "string", "firstViewedAt": "string", "lastViewedAt": "string", "viewCount": 0, "downloadedAt": "string", "linkedInAddedAt": "string" } }}{ "error": "string", "message": "string"}Reinstate a certificate
/certificates/{certificateId}/reinstateAuthorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Path Parameters
Response Body
application/json
application/json
curl -X POST "https://example.com/certificates/string/reinstate"{ "certificate": { "id": "string", "certificateId": "string", "workspaceId": "string", "productId": "string", "courseId": "string", "clientId": "string", "recipientName": "string", "recipientEmail": "string", "courseName": "string", "issuerName": "string", "completionDate": "string", "issuedAt": "string", "issuedBy": "manual", "templateId": "string", "templateVersion": 0, "certificateHash": "string", "pdfStoragePath": "string", "pdfPublicUrl": "string", "verificationUrl": "string", "status": "active", "revokedAt": "string", "expiresAt": "string", "engagement": { "emailStatus": "submitted", "emailStatusAt": "string", "firstViewedAt": "string", "lastViewedAt": "string", "viewCount": 0, "downloadedAt": "string", "linkedInAddedAt": "string" } }}{ "error": "string", "message": "string"}Delete a revoked certificate
/certificates/{certificateId}Authorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Path Parameters
Response Body
application/json
application/json
curl -X DELETE "https://example.com/certificates/string"{ "deleted": true}{ "error": "string", "message": "string"}Resend the certificate email
/certificates/{certificateId}/resend-emailAuthorization
bearerAuth API key from Dashboard → Integrations → API, MCP and CLI.
In: header
Path Parameters
Response Body
application/json
application/json
curl -X POST "https://example.com/certificates/string/resend-email"{ "property1": null, "property2": null}{ "error": "string", "message": "string"}Was this article helpful?

