Build issuance into your own systems
QRCertificates is API-first. Authenticate with a bearer key and automate templates, issuance, batches, and verification from your LMS, SIS, or HR platform.
Base URL & versioning
All endpoints live under the /v1 prefix on your QRCertificates host. In production:
https://qrcertificates.com/v1
Requests and responses are JSON unless noted (template and CSV uploads use multipart form data).
Authentication
Every business endpoint is authenticated with a bearer API key. Create and manage keys in the dashboard under Developers → API keys. A key is shown in full only once, at creation. Send it in the Authorization header (or x-api-key):
curl https://qrcertificates.com/v1/users/me \
-H "Authorization: Bearer ck_your_api_key"
Writes to /v1/keys require an admin role. Revoking a key takes effect within ~60 seconds (auth results are briefly cached; revocation also busts that cache for immediate effect).
Quickstart: issue a certificate
Issue a single credential from a template. It is rendered, hashed, Ed25519-signed, stored immutably, and (if an email is given) delivered — all asynchronously. The response returns immediately with a certCode and a public verifyUrl.
curl -X POST https://qrcertificates.com/v1/issue \
-H "Authorization: Bearer ck_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"templateId": "<template-uuid>",
"recipientName": "Asha Rao",
"recipientEmail": "[email protected]",
"variables": { "course": "Data Science", "score": "92%" }
}'
Response:
{
"id": "5f3c…",
"certCode": "QR-3K9F-2A7D",
"status": "pending",
"isDemo": false,
"verifyUrl": "https://qrcertificates.com/verify?code=QR-3K9F-2A7D"
}
Pass "isDemo": true to mint a free, watermarked test certificate that never verifies as genuine.
Endpoint reference
Templates
| Method | Path | Description |
|---|---|---|
| GET | /v1/templates | List templates (supports limit, offset, category). |
| POST | /v1/templates | Create a template — multipart: background PNG + layout JSON (canvas + positioned fields). |
| GET | /v1/templates/:id | Fetch one template incl. its layout. |
| PATCH | /v1/templates/:id | Update name, category, or layout. |
| DELETE | /v1/templates/:id | Delete a template. |
Issue & certificates
| Method | Path | Description |
|---|---|---|
| POST | /v1/issue | Issue a single certificate (see Quickstart). |
| GET | /v1/certificates | List issued certificates for your org. |
| GET | /v1/certificates/:id | Fetch one certificate. |
| POST | /v1/certificates/:id/revoke | Revoke a credential (optional { "reason": "…" }). It then verifies as revoked. |
| POST | /v1/certificates/:id/send | (Re)email the certificate to its recipient. |
Batches (bulk issuance)
Issue an entire cohort from a CSV (one row per recipient; columns map to template variables), then poll progress.
| Method | Path | Description |
|---|---|---|
| POST | /v1/batches | Multipart: csv file + templateId (+ optional tag). Returns { batchId, total, status }. |
| GET | /v1/batches | List batches. |
| GET | /v1/batches/:id | Poll a batch — total, done count, and status. |
| POST | /v1/batches/:id/send | Email every certificate in the batch. |
Billing & credits
| Method | Path | Description |
|---|---|---|
| GET | /v1/credits | Current prepaid credit balance (one credit is consumed per non-demo issue). |
| GET | /v1/invoices | List GST-breakdown invoices. |
Verification (public, no auth)
Verification is a public GET by certificate code — recipients and employers never need an account. The service independently re-derives the canonical data hash and checks the Ed25519 signature against the platform key, so valid means cryptographically genuine and unrevoked.
curl https://qrcertificates.com/v1/verify/QR-3K9F-2A7D
{
"status": "valid",
"certCode": "QR-3K9F-2A7D",
"recipientName": "Asha Rao",
"course": "Data Science",
"issuedAt": "2026-06-30T10:15:00Z",
"signatureValid": true,
"issuer": { "tier": "domain", "trusted": true, "label": "acme.edu" },
"message": "Certificate is valid."
}
status is one of valid, revoked, invalid, demo, or unknown. The human-facing page is /verify?code=<code>.
Webhooks
Register endpoints under Developers → Webhooks to get a signed POST when events happen: certificate.issued, certificate.revoked, batch.completed. Each delivery body is:
{
"event": "certificate.issued",
"deliveryId": "…",
"createdAt": "2026-06-30T10:15:00Z",
"data": { "certCode": "QR-3K9F-2A7D", "status": "valid", "verifyUrl": "…", "recipientName": "Asha Rao" }
}
Verify authenticity from the X-QRCert-Signature: sha256=<hex> header — it is HMAC-SHA256(rawBody, secret) using the endpoint's signing secret. Delivery is at-least-once; dedupe on X-QRCert-Delivery.
Errors
Errors use standard HTTP status codes with a JSON { "message": "…" } body. Common cases: 401 missing/invalid key, 403 insufficient role, 404 not found, 402/409 out of credits.
Status
Live service status and incident history are published here. For integration help, contact our team.
Issue your first credential in minutes
Start free — no credit card. Design a certificate, issue a verifiable copy, and watch it verify on a public page. Scale to thousands when you are ready.