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.