Developer platform
DocCertify REST API
Issue, list, revoke and verify tamper-evident credentials from your own product. The API is included on every plan. Nothing is paywalled. Base URL: https://doccertify.com/api/v1
Authentication
Create keys in Settings → Developers. Send the key as a Bearer token. Test keys (dc_test_…) behave identically but issue watermarked test credentials that don't count against your plan and never email recipients. Perfect for integration testing.
Authorization: Bearer dc_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxRate limit: 120 requests/min per key. Keys are stored hashed, so treat them like passwords.
Endpoints
POST/api/v1/credentials
Issue a credential. Returns 201 with the credential, its public verify URL and a signed PDF URL.
curl -X POST https://doccertify.com/api/v1/credentials \
-H "Authorization: Bearer dc_test_..." \
-H "Content-Type: application/json" \
-d '{
"recipientName": "Jane Doe",
"recipientEmail": "jane@example.com",
"courseName": "Advanced Data Science",
"expiryDate": "2028-07-17",
"template": "classic",
"customFields": [{ "label": "Grade", "value": "A+" }]
}'Optional: templateId (a Template Studio template UUID), issueDate / expiryDate (YYYY-MM-DD), signatoryIds, template (classic · modern · minimal · elegant · bold), customFields. Errors: 400 validation, 402 plan limit reached, 429 rate limit.
GET/api/v1/credentials?limit=25&offset=0&status=active
List credentials, newest first. status filters by active · revoked · expired. Live keys list live credentials; test keys list test credentials.
GET/api/v1/credentials/{id}
Retrieve one credential by its ID.
DELETE/api/v1/credentials/{id}
Revoke a credential. Verification pages immediately show it as revoked, and a credential.revoked webhook fires.
GET/api/v1/verify/{publicId}
Public, no auth required. Verification must be free for everyone. Returns the credential's validity, issuer, recipient and tamper-evidence status.
curl https://doccertify.com/api/v1/verify/AB12-CD34-EF56Webhooks
Add HTTPS endpoints in Settings → Developers. We POST JSON events (currently credential.issued and credential.revoked), signed Stripe-style so you can verify authenticity.
X-DocCertify-Event: credential.issued
X-DocCertify-Signature: t=1789000000,v1=hex(hmac_sha256(secret, "{t}.{rawBody}"))
{
"id": "evt_…",
"type": "credential.issued",
"created": "2026-07-17T10:00:00.000Z",
"livemode": true,
"data": {
"object": "credential",
"id": "…",
"public_id": "AB12-CD34-EF56",
"recipient_name": "Jane Doe",
"verify_url": "https://doccertify.com/verify/AB12-CD34-EF56",
"status": "active"
}
}Verify the signature (Node example):
import { createHmac, timingSafeEqual } from "crypto";
function verifySignature(header, rawBody, secret) {
const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}How verification stays trustworthy
Every credential carries a SHA-256 fingerprint over its canonical content and an unguessable public ID. Verification recomputes the fingerprint. If anything was altered, the page says so. Verifying is free, unauthenticated and rate-limit friendly by design: credentials should be checked often.
Questions or a missing endpoint? Email support@doccertify.com.