Errors
Every failure raised by the SDK is an instance of PoliPageError or one of its subclasses. The code attribute tells you what went wrong; the request_id attribute is what to quote when filing a support ticket.
The error hierarchy
Section titled “The error hierarchy”PoliPageError is the base catch-all. Two transport-level branches (APIConnectionError and its APITimeoutError subclass) and one HTTP-status branch (APIStatusError, with per-status subclasses like RateLimitError, NotFoundError, BadRequestError) cover every failure mode.
from poli_page import PoliPage, PoliPageError
client = PoliPage()
try: client.render.pdf({"project": "billing", "template": "invoice", "data": {}})except PoliPageError as err: print(err.code, err.request_id, err.message)SDK-internal codes
Section titled “SDK-internal codes”These originate inside the SDK before any HTTP call (or in response to a network-layer failure). They are lowercase.
| Code | When | Recovery |
|---|---|---|
invalid_options | The arguments passed to the PoliPage constructor are invalid (missing api_key, malformed base_url, etc.). | Fix the constructor call. Raised synchronously. |
network_error | TCP/TLS-layer failure reaching the API. | Automatically retried up to max_retries times. |
timeout | The request did not complete within the configured `timeout`. | Automatically retried up to max_retries times. Raise `timeout` if it keeps tripping. |
DOWNLOAD_FAILED | The S3 second-hop download (after `render.pdf` / `render.pdf_stream`) failed. | Re-fetch the descriptor via documents.get(id) — presigned URLs expire after 15 minutes. |
API codes
Section titled “API codes”Returned by the Poli Page API. Uppercase, snake-case. The SDK forwards the code verbatim.
| Code | When | Recovery |
|---|---|---|
INVALID_API_KEY | The API key is malformed or revoked. | Rotate the key in the dashboard. |
MISSING_API_KEY | No API key was provided in the request. | Check the constructor was called with `api_key`. |
NOT_FOUND | The `project/template` slug or document id does not exist. | Verify the slug/id; check the template is published in this environment. |
VALIDATION_ERROR | The `data` mapping does not satisfy the template schema. | Inspect the template schema in the dashboard. |
MISSING_DATA | The request body lacks a required `data` field. | Pass `data={}` (or with values) on every render call. |
QUOTA_EXCEEDED | You exceeded the per-key rate limit or monthly quota. | Automatically retried; bump tier for sustained higher throughput. |
PAYMENT_REQUIRED | The organization's billing is past due. | Update the payment method in the dashboard. |
INTERNAL_ERROR | The API returned 5xx. | Automatically retried; contact support if it persists. |
The full list of API codes lives in the reference.
Example
Section titled “Example”from poli_page import PoliPage, PoliPageError, RateLimitError
client = PoliPage()
try: pdf = client.render.pdf({ "project": "billing", "template": "invoice", "data": {"invoiceNumber": "INV-001", "total": 1280}, })except RateLimitError: # Custom strategy beyond the SDK's built-in retries. pdf = Noneexcept PoliPageError as err: print(f"render failed: {err.code} ({err.request_id})") raise