A certificate of completion looks like one design, but only some of it changes per person. Making everything a layer produces a fragile template. Making too little a layer produces a hand-edited one. These six fields are the ones worth naming.
The six layers
| Layer | Why it changes | Watch for |
|---|---|---|
full_name |
One per recipient | Long names; turn on auto-fit and test the worst case |
course |
One per programme | Titles of two lines or more |
date |
Per completion | Format it before sending; the API does not localize dates |
credential_id |
One per certificate | Use an RFC 9562 UUID, not a counter |
qr (Code layer) |
Verification link | Payload is your URL with the id in it |
signature (image layer) |
Per issuer, if you have several | Must be a public https file ending .png, .jpg, .jpeg, or .webp |
Everything else stays in the design: border, logo, seal, and the fixed sentence “has successfully completed”. Locking it means a typo fix is one template edit, not 200 corrections.
Test with the names that break layouts
Size for the longest realistic name, not “Ada Lovelace”. Render at least these before the run:
- A two-word name and a six-word name, such as “Mariana Fernanda de Oliveira Rodrigues”
- A name with diacritics
- A course title that wraps to two lines
- A name in a non-Latin script, if your audience has them
Use dryRun first
Send "dryRun": true (or ?dryRun=1) with the real payload. It validates layer names and values and returns { "valid": true } with no job and no credit. A misspelled layer returns 422 instead of a certificate with placeholder text, as described under 422 Unprocessable Content.
Colour and contrast
Check the name against the background once, in the template. WCAG 2.1 asks for 4.5:1 for body text and 3:1 for large text, and the check applies to every certificate you issue.
The QR is only as good as the page
The QR code carries a string. Make the string a URL on your domain, and make that page confirm the id. The pipeline around this is in the Certificate Generator API guide, and the full request is in the certificates use case.
FAQ
What fields go on a certificate of completion?
Recipient name, course title, completion date, a credential id, and a verification QR. An issuer signature is a sixth layer when several people sign.
How do I stop long names overflowing?
Turn on auto-fit for the name layer and test the longest realistic name before the run, not the demo name.
Can I validate a certificate payload without spending credits?
Yes. Send dryRun: true with the real payload. jsontoimg validates layers and values and returns valid: true with no job and no credit.
Why use a UUID for the credential id?
A sequential number reveals how many certificates you issued and lets anyone guess a neighbour’s id. An RFC 9562 UUID cannot be guessed.
Related Resources
- How JSON-to-image conversion works — the pillar guide
- Certificate generator API guide — the full pipeline
- Certificates use case — the request
- Build a certificate generator with QR layers — the tutorial