The most common issues we see in support — and how to fix them yourself in under a minute.
API returns 401 invalid_api_key
- Check the header format:
Authorization: Bearer pxd_...— the word “Bearer” and a single space matter. - A key authenticates on the account that created it, and it can only render templates that account owns — a template in someone else's account is
403 template_forbidden, not a 401. - Rotated the key? Old copies stop working within 60 seconds.
API returns 429 rate_limited
You are over your plan's per-minute allowance — 20 requests / minute on Free, 60 on a paid plan. Sleep for the Retry-After seconds in the response before retrying, and pace off the RateLimit-* headers rather than waiting to be refused. Higher throughput comes with a paid plan at /pricing.
PDF text looks blurry or rasterized
- Check the text is real text in your markup, not a raster image containing text.
- A font family the renderer does not have falls back rather than embedding. Use one of the bundled families (see GET /v1/fonts) or inline your own as a base64
@font-face— a remote font URL is refused with400 remote_font_not_allowedrather than silently dropped. - SVGs with embedded raster fills stay raster in PDFs; re-export as pure SVG paths.
Text overflowed / got clipped
A document is HTML, so long strings behave the way they do in a browser: they wrap, and the block below them moves down. If a field can be longer than the space you designed for, give the element room to grow rather than a fixed height, or let the section repeat onto a second page — the PDF paginates automatically.
Image looks pixelated in PDF
- Supply an image at least 2× the size it is displayed at in the layout (target 300 DPI for print).
- WebP and PNG are lossless in PDFs; heavily compressed JPGs won't magically get sharper.
My logo (or another image) is missing from the render
An image the renderer cannot use does not produce a quietly blank document — the render is refused with a 422 and no credit is charged, so you find out on the call rather than in a customer's inbox.
422 image_host_not_allowed— a render only fetches images from storage we control. An arbitrary host on the public internet is refused by design; the error names the hosts that are allowed. Upload the file to your workspace and send that URL.422 image_fetch_failed— the host is allowed but the file did not come back. Check the object still exists and is public.- Either way, a base64
data:URI always works and is never fetched at all. It is the quickest way to prove the rest of the document is right.
Webhook isn't firing
- Confirm the URL is HTTPS and returns a 2xx within 10 seconds. See Webhooks.
- Signature verification failing? The signed payload is
`${t}.${body}`— using just the body will always fail. - Check Account → Webhooks → Recent deliveries for the response body from your server.
Async render stuck in queued
Median queue time is under 2 seconds. If a job has been queued for over 60 seconds:
- Confirm the workspace has credits —
402 insufficient_creditscan be surfaced late for batch jobs. - Still queued after a minute, with credits available? Send us the job id — we can read the queue directly.
Reproducing an error in a support ticket
Every render response carries an X-Pixldocs-Request-Id header, and every error body carries the same value as request_id. (Read endpoints such as /v1/templates and /v1/usage do not carry the header.) Include it — we can look up the exact render in under a minute.
curl -i https://api.pixldocs.com/v1/render \
-H "Authorization: Bearer $PIXLDOCS_API_KEY" \
... | grep -i x-pixldocs-request-id