API Reference
PDF generation
HTML in — yours, or written by the model from an instruction — rendered PDF out.
/v1/documents/generateTwo mutually exclusive modes. Sending both fields, or neither, returns 400.
htmlstringOptionalDirect mode. You already have finished HTML (from an earlier chat response, for example) and just want it rendered. No inference involved — this call doesn't touch a model, works even while your stack's infrastructure is paused for inactivity, and doesn't count against your token quota.
userstringOptionalInstruction mode. Describe what the document should contain; the gateway asks the model for HTML and renders the result — one request instead of two.
systemstringOptionalOnly with user. Replaces your stack's configured system prompt for this
request.
max_tokensintegerOptionalDefault: 8000Only with user. Ceiling on the model's response, up to 16000.
Direct mode
curl -X POST "https://api.trystac.com/v1/documents/generate" \
-H "Authorization: Bearer $STAC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Report</h1><p>already-rendered content</p>"}' \
-o report.pdfInstruction mode
curl -X POST "https://api.trystac.com/v1/documents/generate" \
-H "Authorization: Bearer $STAC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user": "A sales report for August, with one table per region."}' \
-o report.pdfThe response, in both modes, is the PDF as bytes
(Content-Type: application/pdf) — not JSON, save it directly to a file.
HTML must be self-contained
The rendering engine never fetches any URL referenced in the HTML — no
<img src="https://...">, @import, or remote fonts. It runs on shared
infrastructure serving every customer's account, so outbound fetches to
arbitrary URLs are disabled entirely, not filtered. Any such reference is
silently ignored rather than blocking the request — the PDF renders
without it.
Embed images and fonts as data: URIs instead:
<img src="data:image/png;base64,iVBORw0KG...">In instruction mode this rule is already built into the prompt the gateway sends the model. In direct mode, if your HTML came from a separate chat response with a real image URL, either ask the model (via your prompt) to inline it as a data URI, or convert it yourself before calling this endpoint.
Errors
| Status | Meaning |
|---|---|
400 | html and user both sent (or neither), HTML couldn't be rendered, or (instruction mode) the model's response was truncated |
413 | HTML (sent, or model-generated) or resulting PDF page count over the plan's limit |
422 | max_tokens outside the accepted range (instruction mode only) |
429 | Too many generations in flight right now — the server fails fast rather than queuing; retry shortly |
502 | (instruction mode) failed to call the model |
Limits
| Limit | Go | Pro | Max | Enterprise |
|---|---|---|---|---|
| HTML size (sent, or model-generated) | 2 MB | 5 MB | 8 MB | Custom |
| Pages in the resulting PDF | 20 | 50 | 75 | Custom |
The page ceiling is checked after layout but before the final PDF bytes are produced, so an attempt to exceed it fails without extra render cost. In instruction mode, HTML returned by the model passes through the same size check as direct mode — nothing guarantees the model respected the instruction.

