Create and reuse

Set PDF and image options

Use with your agent

Give this prompt to your AI agent. The agent does the task for you.

Read https://thirds.ai/docs/pdf-and-image-options and help me choose PDF or image settings for my design and prepare a request with the right layout, fonts, and dimensions.

These options control paper, page breaks, fonts, headers, and image capture. For your first API request, start with Create your first PDF.

Set a PDF page

Put PDF settings in the pdf object of a POST /v1/pdf request. The default is A4 portrait with zero margins, backgrounds on, and a scale of 1.

Choose a named format, such as A4 or Letter, or set both width and height. Use one of these methods per request. Include a unit such as mm, cm, in, or px with each length. Set landscape: true for a wide page.

The request sets the paper size. A CSS @page size does not override it, so keep your CSS and request settings in agreement. PDF output uses print styles. Check any @media print rules in HTML you import.

Keep content on the right page

Use CSS page breaks to keep a heading with its text or start a new section. A block must fit on one page before break-inside: avoid can keep it together.

CSS
h1,
h2 {
  break-after: avoid;
}
tr,
.total {
  break-inside: avoid;
}
.new-page {
  break-before: page;
}
p {
  orphans: 3;
  widows: 3;
}

Test an invoice with no items, one item, many items, and a long item name. Let rows grow with their text. A fixed row height or overflow: hidden can hide values. Use a real table with thead and tbody for invoice items. Compute amounts in your app and pass the results as template data.

Choose PDF pages

Send pages with canvas data-thirds-page ids when you want a subset, in that order. Omit pages to keep every page. Duplicate or unknown ids return invalid_request with field pages.

A PDF of selected pages still costs one credit. To export the same pages as images, use carousels.

POST /v1/pdf
{
  "html": "<!doctype html><html lang='en'><head><meta charset='utf-8'></head><body><div data-thirds='canvas' data-thirds-page='cover' style='width:400px;height:500px'>Cover</div><div data-thirds='canvas' data-thirds-page='cta' style='width:400px;height:500px'>Action</div></body></html>",
  "pages": ["cta", "cover"]
}

Add headers and page numbers

Headers and footers sit outside the document body. Turn them on with display_header_footer and leave enough top and bottom margin for them. Give each template its own styles. They do not inherit body styles, and their scripts do not run.

This request makes two pages with the same header and a numbered footer:

POST /v1/pdf
{
  "html": "<!doctype html><html lang='en'><head><meta charset='utf-8'><style>body{margin:0;font:15px/1.55 sans-serif}article{break-after:page}article:last-child{break-after:auto}</style></head><body><article><h1>Quarterly report</h1><p>Orders completed: 24</p></article><article><h1>Next steps</h1><p>Send the report to your team.</p></article></body></html>",
  "pdf": {
    "format": "A4",
    "margins": {
      "top": "20mm",
      "right": "12mm",
      "bottom": "20mm",
      "left": "12mm"
    },
    "display_header_footer": true,
    "header_template": "<span style='font-size:9px;width:100%;text-align:center'>Quarterly report</span>",
    "footer_template": "<span style='font-size:9px;width:100%;text-align:center'><span class='pageNumber'></span> / <span class='totalPages'></span></span>"
  }
}

The pageNumber and totalPages classes insert the current page and total page count. Keep header and footer templates small. Put logos and complex layouts in the document body when possible.

Set PDF details and a password

Set pdf.title, pdf.author, and pdf.subject to fill the PDF's document properties. Each accepts up to 256 characters without control characters. When you omit them, the title uses the saved template name and the author uses the account display name, if available. The subject is empty by default.

Set pdf.password when the reader must enter a password to open the file. It accepts 1 to 127 UTF-8 bytes without control characters. A letter such as a uses one byte. Other characters can use more. The renderer applies AES-256 encryption after it creates the PDF.

POST /v1/pdf
{
  "html": "<h1>September report</h1><p>Orders completed: 24</p>",
  "pdf": {
    "title": "September report",
    "author": "Northline Studio",
    "subject": "Monthly order summary",
    "password": "replace-with-your-own-password"
  }
}

Keep the password in your own secure store and share it with the reader through a separate channel. The render response does not return it. To make a file that opens without a password, omit pdf.password.

Use the fonts and assets you need

Include <meta charset="utf-8"> for currency symbols and accented names. Set a font family in CSS and test each language you use. thirds.ai cannot use a font just because it is installed on your laptop.

The renderer includes these font families. Use lang on each text block and dir="rtl" for Arabic or Hebrew.

TextFont family
LatinLiberation Sans, Liberation Serif, Liberation Mono
JapaneseIPAGothic
Simplified ChineseWenQuanYi Zen Hei
ThaiLoma
ArabicNoto Sans Arabic
HebrewNoto Sans Hebrew
DevanagariNoto Sans Devanagari
EmojiNoto Color Emoji

These fonts cover common text in each group. A rare symbol can still need a licensed font that includes it. Set the family by name when the design needs a specific font.

Use your brand kit for saved designs. For direct HTML, load a licensed web font with @font-face or choose a generic family such as sans-serif. Images can use an uploaded private reference, a public HTTPS URL, or a supported inline data format. thirds.ai cannot read your local files through relative paths or file:// URLs.

thirds.ai checks the addresses of fonts, images, and styles. It rejects private network hosts and unsafe redirects. If a remote font or image changes, later output can change even with the same HTML. Keep asset versions fixed when you need a stable layout. See retries and limits if an asset fails to load.

Upload an image once

Upload a still PNG, JPEG, or WebP file before you save or render a template. Send the raw file bytes with its media type:

Shell
curl https://thirds.ai/v1/image-assets \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: image/png" \
  --data-binary @photo.png

The reply gives you a reference, such as asset://asset_0123456789abcdef0123456789abcdef, plus the image width and height. Use that exact reference in an HTML body image src. You can also pass it as template data, for example <img src="{{ photo }}" alt="Product"> with photo set to the reference.

Uploads are private and free. The reference works only for your account. It stays fixed so saved versions and later renders use the same bytes. An upload can be up to 10 MiB. Images and brand files share a 100-file, 100 MiB account limit. One render can use up to 20 MiB of image bytes. A missing or foreign reference fails before a render job or charge. Put uploaded images in the document body. Private references don't work in PDF header or footer templates. See the API reference for the full limits.

In the editor, choose Image, then Upload image. Uploaded images show in the design canvas. Remote image URLs stay hidden in browser previews. Exports fetch them through the protected render service.

Make a static image

Use POST /v1/image with image.format, image.width, and image.height. thirds.ai captures the rectangle you specify at device scale 1. It does not scroll to capture more content. Anything beyond that rectangle falls outside the image.

POST /v1/image
{
  "html": "<!doctype html><html lang='en'><head><meta charset='utf-8'><style>*{box-sizing:border-box}body{margin:0;background:#0a46ff;color:white;font:32px/1.4 sans-serif}main{padding:64px}h1{font-size:64px;margin:0 0 24px}</style></head><body><main><h1>September report</h1><p>24 orders completed</p></main></body></html>",
  "image": {
    "format": "png",
    "width": 1200,
    "height": 630,
    "transparent": false
  }
}
FormatChoose it forOptions
pngSharp text and flat coloursSupports transparency. Omit quality.
jpegPhotosquality is 1 to 100 and defaults to 80. Transparency must be false.
webpSmaller images with text or photosquality is 1 to 100 and defaults to 80. Supports transparency.

The default size is 1280 by 720 pixels. Width can be 320 to 7680 pixels, and height can be 200 to 4320 pixels. The total must also fit the pixel limit. For transparent PNG or WebP, set transparent: true and leave the HTML background transparent too. The Open Graph image generator page uses this same fixed-size capture for a 1,200 by 630 link-preview card.

Add sizes and export a pack

On a saved image template, open Sizes and add the presets or a custom width and height. The layout adapts to each canvas for free. You can still edit one size by hand. Save writes every size in the new version.

Export pack creates one image job per size. Each successful file costs one credit. Failed sizes cost nothing, and Retry failed only reruns those jobs. The ZIP keeps the requested order, with names such as 01-story.png.

POST /v1/image-packs
curl --fail-with-body --silent --show-error https://thirds.ai/v1/image-packs \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: YOUR_UNIQUE_PACK_REQUEST' \
  --data '{"template_id":"tpl_00000000000000000000000000000000","version":1,"data":{"headline":"Autumn sale"},"format":"png","sizes":["original","square-post","story"]}'

Poll GET /v1/image-packs/{id} until every size has succeeded or failed, then download archive_url. See the image packs reference.

Make many files from a CSV

To fill one saved template once per data row, upload a CSV batch. Each successful file costs one credit. The ZIP names files 001.pdf in row order.

Finish JavaScript before capture

JavaScript is off by default. Send finished HTML for invoices and other fixed data when you can. If a chart needs JavaScript, set javascript.mode to enabled. Set the ready marker after the chart is complete:

JavaScript
document.documentElement.dataset.thirdsRenderReady = "true";

The renderer waits up to two seconds for this marker, then stops scripts once it is ready. Set the marker only after fonts, data, and chart drawing finish. If the marker is missing, the render fails with javascript_readiness_timeout. The renderer blocks browser navigation, popups, nested frames, and background workers.

Next, download the finished file. See credits and billing for output and preview costs. If you are replacing wkhtmltopdf, follow the migration guide.

For a complete two-page recipe, read How do I control page breaks, headers, and fonts in HTML to PDF?.

Ready to make your first file?

Start in the playground with a gallery template, or get an API key and send your first request from your own terminal.