In the previous guide we designed a certificate: a title, a recipient's name, a course, a date, all laid out and looking right. But every value on it is fixed. Hand it to a hundred graduates and you'd be editing the same file a hundred times.
The fix is to treat the design as a template: mark the handful of fields that change (the name, the course, the date) as variables, then let the ImaginePDF API fill them in. One design, one call per PDF, any number of certificates.
This guide does exactly that. We'll mark two or three fields as variables in the editor, then generate a filled PDF over the REST API. A certificate is a nice place to start because it's almost all text, but the same flow works for any design.
Mark a field as a variable
Open your certificate in the visual editor and click the field you want to make fillable, say the recipient's name. A small toolbar appears above it. The lightning-bolt (⚡) button is the one you want; its tooltip reads Make Dynamic.
Click it and the field changes: it picks up a dashed orange outline, and a little badge appears above it with a name you can type into. That name is the variable; call it recipient_name. That's the whole gesture: select, click the bolt, name it.
A "dynamic" field is just a field whose text comes from outside the design. The styling you set (font, size, color, position) stays exactly as you designed it; only the words get swapped in at generation time.
Name two or three fields
Do the same for the other parts that change. For a certificate that's usually just:
recipient_name: who it's forcourse_name: what they completeddate: when
Pick names you'll recognize later, because these become the field names in your API call. Use letters, numbers, and underscores; no spaces. Every field you mark shows up in the Variables panel on the right, so you can see the full list at a glance, rename one, or remove it.
Keep it to the few fields that genuinely change. Everything else (the heading, the seal, the signature line) stays baked into the design.
Open the Generate-via-API panel
With your variables named, click API in the editor's top bar. The Generate via API panel slides out with everything you need to make the call:
- the endpoint, already pointing at this design
- a ready-to-copy snippet in cURL, JavaScript, or Python
- the field names it expects, the same ones you just created
The design is addressed by its ID, which you'll see in the endpoint (and in the editor URL, after ?design=). There's nothing to publish first; any saved design can be generated.
Create an API key
The call authenticates with an API key. If you don't have one yet, open Settings → API Keys in your dashboard and create one. It looks like pc_live_…, it's tied to your workspace, and it's shown only once, so copy it somewhere safe. You'll send it on the X-API-Key header.
If you already set one up for the Claude plugin, the same key works here.
Fill the fields and generate
Now the call itself. Take the cURL snippet from the panel and fill in your values, one entry per variable, keyed by the name you gave it:
curl -X POST 'https://api.imaginepdf.com/api/v1/designs/YOUR_DESIGN_ID/generate' \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"data": {
"recipient_name": "Jane Doe",
"course_name": "Advanced TypeScript",
"date": "26 June 2026"
}
}'The response hands back a link to the finished PDF:
{
"status": "success",
"data": {
"filename": "certificate.pdf",
"downloadUrl": "https://files.imaginepdf.com/..."
},
"error": null
}Open downloadUrl and there's your certificate, with Jane's name, course, and date dropped into the exact spots you marked. The JavaScript and Python tabs in the panel make the same call if you'd rather not use cURL; they read the link straight off data.downloadUrl.
One design, many PDFs
That's the payoff. The design stays put; only the data changes. Call the endpoint again with a different name and course and you get another certificate, identical in every way except the words you chose to vary:
{
"data": {
"recipient_name": "John Smith",
"course_name": "Intro to Rust",
"date": "26 June 2026"
}
}A single design now backs every certificate you'll ever send: no redrawing, no fragile layout code, just a clean call with the values that change. Open it in the visual editor any time to adjust the look, or revisit the design guide to build your next template from scratch.