Workspace API

Certificates

Certificates endpoints of the Zanfia Workspace API, with schemas and code samples.

6 min readLast updated Sep 10, 2026

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

GET/certificates

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Query Parameters

productId?string

Course product id — omit for all courses.

Length1 <= length
limit?integer

Max rows, newest first (max 500; the service default applies when omitted).

Range0 < value <= 500

Response 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)

POST/certificates/issue

Authorization

bearerAuth
AuthorizationBearer <token>

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

GET/certificates/templates

Authorization

bearerAuth
AuthorizationBearer <token>

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

POST/certificates/templates

Authorization

bearerAuth
AuthorizationBearer <token>

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

GET/certificates/templates/{templateId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

templateId*string

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

PATCH/certificates/templates/{templateId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

templateId*string

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

DELETE/certificates/templates/{templateId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

templateId*string

Response Body

application/json

application/json

curl -X DELETE "https://example.com/certificates/templates/string"
{  "deleted": true}
{  "error": "string",  "message": "string"}

Revoke a certificate

POST/certificates/{certificateId}/revoke

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

certificateId*string

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

POST/certificates/{certificateId}/reinstate

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

certificateId*string

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

DELETE/certificates/{certificateId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

certificateId*string

Response Body

application/json

application/json

curl -X DELETE "https://example.com/certificates/string"
{  "deleted": true}
{  "error": "string",  "message": "string"}

Resend the certificate email

POST/certificates/{certificateId}/resend-email

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

certificateId*string

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?

Related articles

Spotted something off? Tell us at support@zanfia.com.