Why we don't just email you the PDF
The simplest possible design for a rendering API is: you send data, we email you a PDF. No signed URLs, no expiry, no storage layer to think about. We didn’t build it that way, and it’s worth explaining why.
An attachment is a permanent copy, whether you meant it to be or not
Once a PDF lands in an inbox, it’s replicated into every backup, every mail server log, every device that syncs that inbox — indefinitely, by default. For an invoice, that’s usually fine. For a document with a customer’s full financial detail or a signed contract, “lives forever in an email thread neither party controls” is not a property most teams actually want, even if nobody thought to ask for the opposite.
A signed URL makes the retention period a decision, not a default
Setting a TTL means the file exists for exactly as long as you decided it should — an hour for a one-time download link, 30 days for something a customer needs to revisit, or zero to stream the bytes straight through with nothing persisted at all. The point isn’t that short-lived is always correct; it’s that someone chose, instead of “forever” happening by accident because that’s what email does.
It also makes delivery your choice, not ours
A signed URL is just a link — you can email it, sure, but you can also post it to Slack, hand it to a mobile client, or store it in your own system of record next to the customer it belongs to. Baking delivery into the render step would mean picking one channel and making everyone else work around it.
None of this is a security feature bolted on after the fact — it’s the reason the API is shaped the way it is. A render returns a URL, not a file, because the URL is the thing that lets you decide how long that document should exist and who should be able to reach it.
Set your own TTL on the next render
An hour, thirty days, or zero and streamed straight through — the retention period is a request parameter, not a default you're stuck with.