Skip to content
Certquill

Certquill API

Issue certificates from your own systems: an LMS after course completion, a webinar tool after attendance, a Zapier/Make/n8n workflow. The API is available on Pro and Business plans. Create a key under Settings → API keys.

Basics

  • Base URL: https://certquill.zentez.io/api/v1
  • Authentication: Authorization: Bearer cq_live_… (keys are shown once; store them like passwords).
  • Content type: JSON in, JSON out. Errors return { "error": { "code", "message" } }.
  • Rate limit: 600 requests per minute per key (429 with Retry-After).
  • Credits: each issued certificate uses one credit from your plan allowance, then packs. 402 insufficient_credits when you run out.

Issue certificates

POST /api/v1/certificates — up to 1,000 recipients per call. Delivery emails are queued automatically when send_email is true and a recipient has an email.

curl -X POST https://certquill.zentez.io/api/v1/certificates \
  -H "Authorization: Bearer cq_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "design_id": "dsg_abc123",
    "send_email": true,
    "email_message": "Congratulations on finishing the course!",
    "recipients": [
      { "name": "Priya Raghunathan", "email": "priya@example.com", "course": "Data Engineering Bootcamp", "date": "2026-08-30" },
      { "name": "Arjun Mehta", "email": "arjun@example.com", "course": "Data Engineering Bootcamp", "custom": { "Grade": "A" } }
    ]
  }'

Response 201:

{
  "data": [
    {
      "id": "CQ-7K3MQ2ZPX4",
      "recipient_name": "Priya Raghunathan",
      "recipient_email": "priya@example.com",
      "course": "Data Engineering Bootcamp",
      "date": "2026-08-30",
      "status": "active",
      "email_status": "queued",
      "verify_url": "https://certquill.zentez.io/verify/CQ-7K3MQ2ZPX4",
      "pdf_url": "https://certquill.zentez.io/c/CQ-7K3MQ2ZPX4/pdf",
      "png_url": "https://certquill.zentez.io/c/CQ-7K3MQ2ZPX4/png",
      "design_id": "dsg_abc123",
      "batch_id": null,
      "view_count": 0,
      "created_at": "2026-09-02T10:00:00.000Z"
    }
  ],
  "credits": { "used": 2, "from_plan": 2, "from_pack": 0 }
}

Fields per recipient: name (required, ≤120 chars), email, course (fills {{course}}), date (YYYY-MM-DD, fills {{date}}; defaults to today), custom (object; use {{custom.Key}} in the design body).

List certificates

GET /api/v1/certificates?limit=100&email=priya@example.com&before=CQ-… — newest first. Use next_before from the response as the before cursor for the next page.

Get, revoke, restore

GET   /api/v1/certificates/CQ-7K3MQ2ZPX4
PATCH /api/v1/certificates/CQ-7K3MQ2ZPX4   { "status": "revoked", "reason": "Issued in error" }
PATCH /api/v1/certificates/CQ-7K3MQ2ZPX4   { "status": "active" }

Revoked certificates show a “Revoked” state on their verification page and the PDF download is disabled.

Designs and account

GET /api/v1/designs   → [{ "id", "name", "template", "title", "placeholders": ["course","date"] }]
GET /api/v1/me        → { "plan", "credits": { "plan_remaining", "pack", "total", "period_end" } }

Idempotency and retries

Issuing is not automatically idempotent: retrying a request that succeeded creates duplicates. Check the response (or list by email) before retrying after a network error. Emails are deduplicated internally, so a certificate is never emailed twice for one issue.

Automation tools

Zapier, Make and n8n can call this API with their generic HTTP/Webhook modules: set the method to POST, add the Authorization header, and map your trigger fields into the recipients array. A native Zapier app is planned; email support if you need it sooner.