Skip to content

Templates ​

Templates are the design of your mail. They are authored in the web app and are read-only over the API — the templates permission has a single action, templates:read.

Why authoring is not programmable

A campaign produces paper. Once printed, nothing can be corrected. A template is therefore created in the web app's editor, where you see exactly what will be printed before you commit to it. Creating, updating and deleting templates are web-app-only operations; an API key calling them receives 403 Forbidden: API keys cannot access this resource.

These endpoints exist so your integration can discover the template ids it needs. See Templates.

List templates ​

GET/api/v1/templates
requires templates:read

Cursor-paginated, newest first. Requires templates:read. Only templates you authored are returned — the internal, immutable content snapshots the platform creates per campaign are never listed.

Query parameters ​

ParameterTypeDefaultNotes
cursoruuid—An id from a previous page
limitinteger201–100
directionnext | prevnextPage direction
searchstring—≤200 characters. Case-insensitive substring match on the template name
bash
curl -H "x-api-key: drse_your_api_key" \
  "https://api.utskick.dr.se/api/v1/templates?search=summer"
ts
const params = new URLSearchParams({ search: "summer" });
const res = await fetch(`https://api.utskick.dr.se/api/v1/templates?${params}`, {
  headers: { "x-api-key": process.env.DRSE_API_KEY! },
});
const { data } = await res.json();
const template = data[0];
// `template.id` is what you pass as `templateId` when creating a campaign.

200 OK

json
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "name": "Summer postcard",
      "kind": "user",
      "hasBackPage": true,
      "qrCodeUrl": "https://example.com/promo",
      "qrCodeDescription": "Landing page",
      "qrCodeTrackingEnabled": true,
      "createdAt": "2026-07-20T08:00:00.000Z",
      "updatedAt": "2026-07-24T16:12:00.000Z"
    }
  ],
  "meta": { "count": 3, "nextCursor": null, "prevCursor": null }
}
FieldNotes
kindAlways user on this endpoint
hasBackPageWhether the mail is printed double-sided
qrCodeUrlThe template's default QR destination, or null. A campaign built from this template inherits it unless you send your own qrCode

Failures ​

StatuscodeWhen
400validation_failedInvalid limit, cursor, direction, or search over 200 characters
401unauthorizedKey problem
403forbiddenKey lacks templates:read

Retrieve one template ​

GET/api/v1/templates/:id
requires templates:read

Requires templates:read. Returns the template plus short-lived download URLs for its assets.

bash
curl -H "x-api-key: drse_your_api_key" \
  https://api.utskick.dr.se/api/v1/templates/550e8400-e29b-41d4-a716-446655440002
ts
const id = "550e8400-e29b-41d4-a716-446655440002";
const res = await fetch(`https://api.utskick.dr.se/api/v1/templates/${id}`, {
  headers: { "x-api-key": process.env.DRSE_API_KEY! },
});
const { data } = await res.json();
console.log(data.mode, data.hasBackPage, data.images.length);

200 OK

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440002",
    "name": "Summer postcard",
    "mode": "editor",
    "hasBackPage": true,
    "frontContentUrl": "https://storage.example/templates/.../content.json?X-Amz-Signature=...",
    "backContentUrl": "https://storage.example/templates/.../back-content.json?X-Amz-Signature=...",
    "logoUrl": "https://storage.example/templates/.../logo.png?X-Amz-Signature=...",
    "returnAddress": "DRSE, Box 1, 111 11 Stockholm",
    "returnAddressLogoUrl": null,
    "qrCodeUrl": "https://example.com/promo",
    "qrCodeDescription": "Landing page",
    "qrCodeTrackingEnabled": true,
    "images": [
      {
        "key": "templates/550e8400.../images/018f....png",
        "url": "https://storage.example/...?X-Amz-Signature=...",
        "page": "front",
        "x": 20,
        "y": 90,
        "w": 60,
        "h": 40,
        "layer": "above",
        "fit": "contain",
        "ordinal": 0
      }
    ],
    "createdAt": "2026-07-20T08:00:00.000Z",
    "updatedAt": "2026-07-24T16:12:00.000Z"
  }
}
FieldNotes
modeeditor for a template designed in the editor, pdf for one backed by an uploaded PDF
frontContentUrl / backContentUrlPresigned URLs to the stored design document. backContentUrl is null for single-sided templates
logoUrl, returnAddressLogoUrlPresigned image URLs, or null
returnAddressThe text printed as the sender. A campaign inherits it unless you send your own
images[]Placed images. x/y/w/h are millimetres from the top-left of the A4 page; ordinal is draw order; layer is whether the image sits above or below the text

Asset URLs expire

frontContentUrl, backContentUrl, logoUrl, returnAddressLogoUrl and each images[].url are presigned and short-lived. Use them immediately; do not store or share them. Re-request the template to get fresh URLs.

Failures ​

StatuscodeWhen
400validation_failedid is not a UUID (Template ID must be a valid UUID)
401unauthorizedKey problem
403forbiddenKey lacks templates:read
404not_foundTemplate not found — unknown id, a template in another account, or an internal campaign snapshot

Campaign templateId is not a template you can fetch

The templateId in a campaign response is an internal snapshot of the content at the moment the campaign was created. Fetching it returns Template not found by design. Keep your own record of which authored template you used.