Help centre

How can we help?

Answers to what people actually ask. Nothing here replaces the API reference — this is the practical layer on top of it. Still stuck? The chat in the corner reaches a person, as does [email protected].

Getting started

How do I get an API key?
Create an account at /account/signup/ and confirm the email we send. The key appears in your dashboard the moment the address is verified. It is shown once — copy it then, because we store only a hash and cannot show it again. If you lose it, revoke that key and create another.
What is the fastest way to see it work?
One request, no SDK:
curl -X POST https://pdfgeny.com/api/v1/render -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"html":"<h1>Hello</h1>"}' --output hello.pdf
If you would rather not sign up first, the HTML to PDF converter runs the same engine in the browser.
Do I need a credit card?
No. The free plan gives 50 documents a month indefinitely, with a small footer line on each document. A card is only needed if you move to a paid plan.
Which endpoint should I use?
Use /v1/render when the caller can wait a second or two. Use /v1/jobs when a person is waiting on the other end — it returns immediately and calls your webhook when the document is ready. Use /v1/batch for more than a handful of documents at once.

Accounts and keys

Can I have more than one key?
Yes, up to ten active keys per account. Give each environment its own key — production, staging, that script on someone's laptop — so you can revoke one without breaking the others.
How do I revoke a key?
In the dashboard, next to the key. Revocation is immediate: requests with that key start returning 401 invalid_api_key within a second.
I lost my key. Can you resend it?
No — we store only a SHA-256 hash, so nobody at PDFGeny can read your key, including us. Revoke it and create a new one.
Can I sign in without a password?
Yes. Leave the password field empty on the sign-in page and we email a one-time link, valid for 30 minutes.
How do I delete my account?
Email [email protected] from the address on the account. We delete within 30 days, keeping only records we are legally required to retain, such as payment history for tax purposes.

Rendering

My PDF is missing background colours.
Set "print_background": true. It is on by default in our API, but off by default in raw Puppeteer and in the browser's print dialog, which is where most templates are first tested.
The page is empty or half-rendered.
Rendering started before JavaScript finished. Pass wait_for with a CSS selector that only exists once content is drawn, or a millisecond value up to 15000. Charts and dashboards almost always need this.
The wrong font appears.
Six causes, all common: the font was still loading, CORS blocked it, the URL was relative in inline HTML, the format is too old, the font only exists on your machine, or the licence forbids embedding. Full diagnosis here.
Table rows split across pages.
Add tr { break-inside: avoid } and thead { display: table-header-group } so headers repeat. See page breaks in HTML to PDF.
The PDF looks different from Ctrl+P in my browser.
Same engine, different defaults: print media emulation, background graphics, page size, margins and viewport width. The six differences.
Can I render a page that needs a login?
Yes, if the URL carries its own authentication — a signed token in the query string, for example. We do not store credentials, and the renderer has no session of its own.
What is the maximum document size?
HTML payloads up to 2 MB, rendered documents up to 25 MB. Larger HTML usually means an embedded image; link it instead of inlining it.

Templates

How do I use a template from the API?
Send its id and your data: {"template":"invoice","data":{"client":"Acme","total":"149.00"}}. Field names come from GET /api/v1/templates, and any field you omit uses the template's example value.
Can I change a template's design?
The built-in templates are fixed, but you can send your own HTML to the same endpoint and get identical treatment. Most people start from a template's output, adjust the CSS, and switch to html.
Do line totals calculate automatically?
Yes. Send quantity and unit price and the amount is computed server-side, so the document cannot disagree with your own arithmetic. Send the grand total explicitly — it should come from your ledger, not from a template.
Can I add my logo?
Yes, in your own HTML. Reference it by absolute URL or embed it as a data URI; relative paths have nothing to resolve against when you POST markup.

Billing

What counts as a document?
One successful render is one document, regardless of page count. Failed renders are never counted.
What happens when I hit my quota?
Requests return 429 quota_exceeded with the plan and limit in the message, until the counter resets on the first of the month. If you enable overage, extra documents are billed at your plan's rate instead.
How do I change or cancel my plan?
From the billing page in your dashboard. Upgrades apply immediately; cancellations keep the plan until the end of the paid period. Nothing is deleted when you drop to Free — keys and history stay.
Do you charge per user?
No. Plans are priced by documents. Create as many keys and involve as many teammates as you like.
Do you accept cryptocurrency?
Yes, for prepaid monthly or yearly periods (USDT, BTC, ETH). Email [email protected] and we will set it up.
Can I get an invoice for my payment?
Every Stripe payment produces one, downloadable from the billing page. For a company invoice with specific details, write to us.

Errors and limits

What do the error codes mean?
Every error has the same shape: {"error":{"code":"…","message":"…"}}. invalid_api_key — revoked, or email not confirmed. quota_exceeded — monthly limit. rate_limited — too many per second. too_many_concurrent — too many at once. render_failed — the markup or URL did not render; the message says why. payload_too_large — HTML above 2 MB.
What are the rate limits?
Per key: Free 1 request/second and 1 concurrent render; Starter 5 and 3; Growth 10 and 5; Scale 20 and 10. Queued jobs are exempt from the concurrency limit — that is what they are for.
Should I retry a failed request?
Retry rate_limited with exponential backoff. Do not retry invalid_input or render_failed — they will fail identically.
How long do stored documents live?
Seven days, then they are deleted permanently. Download or copy anything you need to keep; regenerating is always possible if you kept the source data.

Not covered here? Open the chat, or email [email protected]. Include your key prefix (the first ten characters) and, if a render failed, the exact error message — that usually turns a day of back-and-forth into one reply.