Appearance
PDF campaigns
Instead of a template, send a print-ready PDF. Your pages become the background; only the postal address blocks are drawn on top.
A fully supported programmatic path: you produced the PDF, so you can open it and confirm what will print — exactly what raw editor content cannot offer.
How to send one
PDF mode is multipart only — a file part cannot be expressed in JSON.
bash
curl -X POST "$DRSE_BASE_URL/api/v1/campaigns" \
-H "x-api-key: $DRSE_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F "name=Autumn flyer" \
-F "pdf=@flyer.pdf;type=application/pdf" \
-F "hasBackPage=true" \
-F "listId=550e8400-e29b-41d4-a716-446655440001"ts
import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("name", "Autumn flyer");
form.append(
"pdf",
new File([await readFile("flyer.pdf")], "flyer.pdf", {
type: "application/pdf",
}),
);
form.append("hasBackPage", "true");
form.append("listId", "550e8400-e29b-41d4-a716-446655440001");
const res = await fetch(`${BASE}/api/v1/campaigns`, {
method: "POST",
headers: {
"x-api-key": KEY,
"Idempotency-Key": crypto.randomUUID(),
},
body: form,
});Any recipient source works — listId, recipients, or a recipientsFile part alongside the PDF.
Looking for a 210×99 mm card instead of an A4 letter? That is the same upload with format=postcard — see Postcards.
What PDF mode forbids
| Field | Why |
|---|---|
templateId | The PDF is the content; there is nothing to inherit |
content, backContent | Same |
qrCode | Through this API, yes: put your own QR image in the PDF. In the web app a code can be placed on an upload by dragging it onto the preview |
Sending any of them with a pdf part is a 400 naming the conflicting field.
hasBackPage is the opposite: it is only valid in PDF mode. Sending it without a PDF is a 400 hasBackPage only applies to PDF campaigns.
Front and back
hasBackPage | Result |
|---|---|
omitted / false | Page 1 is printed as the front. Any further pages are ignored |
true | Page 1 front, page 2 reverse |
Two pages is the maximum in one campaign.
What you are responsible for
The API checks less than you might assume
Validation is limited to:
- the part is declared
application/pdf, - it is at most 20 MB,
- the bytes actually begin with a PDF signature.
Page dimensions and page count are not enforced. A PDF that is not A4, or is scaled or rotated, is accepted and printed as-is. Getting this wrong produces misaligned mail that has already been paid for.
Before your first real send, confirm:
| Check | Requirement |
|---|---|
| Page size | A4 — 210 × 297 mm |
| Pages | 1, or 2 with hasBackPage: true |
| Orientation | Portrait |
| Fonts | Embedded |
| Colour | CMYK or RGB, consistently |
| Reserved zones | Kept clear — see below |
Keep the address zones clear
The platform draws the destination address, the return address and a postage band onto the front page. Artwork underneath them will be printed over and the mail may be undeliverable.
On a 210 × 297 mm front page, measured from the top-left corner:
| Zone | Position | Size |
|---|---|---|
| Return address | 17 mm, 16 mm | 58 × 17 mm |
| Postage band | 121 mm, 32 mm | 77 × 5 mm |
| Destination address | 121 mm, 44 mm | 77 × 20 mm |
The safest approach is to treat the whole band from the top of the page down to 77 mm as reserved, and keep a 5 mm margin on the other edges. That is the same safe area the web app's editor enforces visually.
The reverse page has no reserved zones beyond a 5 mm production margin.
Testing without mailing
There is no dry-run or proof endpoint. To validate a PDF end to end, send a campaign to a single recipient — your own address — and inspect the letter that arrives. Do this once per PDF layout before any volume send.
Failure reference
| Status | code | Message |
|---|---|---|
| 400 | validation_failed | File must be a PDF — the part was not application/pdf |
| 400 | validation_failed | PDF must be under 20 MB |
| 400 | validation_failed | File is not a valid PDF — the bytes are not a PDF |
| 400 | validation_failed | A conflicting field was sent (templateId, qrCode, backContent) |
| 413 | payload_too_large | Request body too large. Maximum 40MB. — the whole multipart body |
Note the 20 MB PDF cap surfaces as 400, while the 40 MB total-body cap surfaces as 413.
Templates can also be PDF-backed
Separately, a template authored in the web app may itself be backed by an uploaded PDF — GET /api/v1/templates/:id reports mode: "pdf". Referencing one by templateId is a normal template campaign, previewed in the web app.
Choose based on where the artwork lives: your pipeline (send a pdf part) or the web app (use templateId).
Next
- Campaign from a PDF — full walkthrough
- Campaigns — content and recipient sources