Output handling
The SDK gives you four ways to handle a rendered PDF: in-memory bytes, a PSR-7 stream, a write-to-disk helper, or a stored document on the server. Pick the one that matches how your code consumes the output.
In-memory (render->pdf)
Section titled “In-memory (render->pdf)”use PoliPage\RenderInput;
$pdf = $client->render->pdf(new RenderInput( project: 'billing', template: 'invoice', data: ['invoiceNumber' => 'INV-001'],));// $pdf: binary string — write, upload, or return as-is.Best for documents that fit comfortably in process memory.
Streaming (render->pdfStream)
Section titled “Streaming (render->pdfStream)”For large PDFs or piping straight to an HTTP response or object store, use pdfStream() and let the SDK keep memory bounded. The return value is a PSR-7 StreamInterface.
$stream = $client->render->pdfStream(new RenderInput( project: 'billing', template: 'invoice', data: ['invoiceNumber' => 'INV-001'],));// $stream: Psr\Http\Message\StreamInterface — read in chunks, pipe to a response.The client’s timeout bounds the wait for the first byte and each gap between two chunks, not the whole stream, so a large PDF read at your own pace is not cut off. A stall past it raises DOWNLOAD_FAILED (Failed to download PDF: timeout), from pdfStream() itself or from the read. A body that ends before its announced length raises DOWNLOAD_FAILED (Failed to download PDF: network error).
With Guzzle, this download goes through Guzzle’s stream handler (PHP’s HTTP stream wrapper) rather than cURL: cURL options set on your Guzzle client do not apply to it, and it needs PHP’s allow_url_fopen. render->pdf() and downloadPdf() still use cURL.
Read the PSR-7 stream directly (or use renderToFile()): a PHP stream resource made from it with GuzzleHttp\Psr7\StreamWrapper (guzzlehttp/psr7 3.x) cannot report a failed download, and a copy from it can come out short without an error.
Write to file (renderToFile)
Section titled “Write to file (renderToFile)”The renderToFile() free function (autoloaded from src/render_to_file.php) streams bytes directly to disk with bounded memory. Parent directories are created automatically.
The bytes go to a temporary file next to the target, renamed into place only once the PDF is complete: if the render, the download or the write fails, the target is left as it was. A file that cannot be written raises io_error with the message Failed to write PDF: <reason> (PHP’s own error text, also chained as getPrevious()); it has no status and is never retried. The rename replaces the target file, so an existing file’s permissions, owner and hard links are not kept, and a symlink at the path is replaced rather than followed. A process killed mid-download can leave a .<name>.<random>.part file next to the target.
use function PoliPage\renderToFile;
renderToFile( $client, new RenderInput(project: 'billing', template: 'invoice', data: []), './out.pdf',);Server-side storage (render->document)
Section titled “Server-side storage (render->document)”When you want the PDF to live on Poli Page’s servers (for later download, preview, or thumbnails), use render->document(). It returns a DocumentDescriptor with documentId, presignedPdfUrl, and a downloadPdf() method.
$doc = $client->render->document(new RenderInput( project: 'billing', template: 'invoice', data: ['invoiceNumber' => 'INV-001'],));$pdf = $doc->downloadPdf();presignedPdfUrl has a 15-minute TTL. If it expires, call $client->documents->get($documentId) to refresh.
Example
Section titled “Example”<?php
require __DIR__ . '/vendor/autoload.php';
use PoliPage\PoliPage;use PoliPage\RenderInput;
use function PoliPage\renderToFile;
$client = PoliPage::client($_ENV['POLI_PAGE_API_KEY']);
renderToFile( $client, new RenderInput( project: 'billing', template: 'invoice', data: ['invoiceNumber' => 'INV-001'], ), './invoices/INV-001.pdf',);