Accounts and billing
There’s no dashboard and no password. You sign in with an email link, and you manage everything from the CLI, the SDKs or the API.
Sign in
npx quirepdf-cli login you@example.com
- The CLI shows a 6-digit code and waits. Quire emails you a sign-in link. The link works once and expires after 15 minutes.
- Open the link and enter the code from your terminal, then select Approve sign-in.
- The CLI collects your new API key and saves it to
~/.config/quire/config.json. The key is never shown on a web page.
The code is never in the email, so a sign-in can only be approved by someone who can see the terminal that started it. Opening the link on its own changes nothing, so email security scanners that open links can’t approve a sign-in. After five wrong codes the sign-in is cancelled.
The first sign-in creates your account on the free plan. No card is needed. If the CLI already has a working key, login says so and creates nothing; use --force to sign in again. Each new sign-in adds a key named after the device (quirepdf-cli on your-laptop), and your other keys keep working.
The sign-in request returns the same response whether or not an account exists for that email, so nobody can use it to find out who has an account.
One account per mailbox
Addresses that deliver to the same mailbox share one account and one free quota. A +tag is ignored, and so are dots in Gmail addresses, so you+test@gmail.com and y.ou@googlemail.com sign in to the account for you@gmail.com. Disposable-inbox domains can’t sign up (400 disposable_email).
Sign-in requests are limited to 10 an hour from one network and 5 an hour for one mailbox (429 rate_limited).
Signing in from your own code
The CLI uses three public endpoints, which agents and scripts can use too:
curl https://api.quirepdf.dev/v1/login \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","device":"billing-worker"}'
{
"login_id": "lg_tvW6d9A9pv5Ma8YPkwlA",
"code": "482913",
"expires_in": 900,
"message": "check your email for a sign-in link, then enter this code on the page it opens"
}
Show the code to the person signing in. device is optional and names the new key. Then poll GET /v1/login/{login_id} every couple of seconds:
202 {"status":"pending"}until the sign-in is approved with the code;- then
200 {"status":"ready","api_key":"qk_live_..."}, exactly once; - after that, or once the sign-in expires or is cancelled,
410 login_gone.
API keys
Keys look like qk_live_ followed by 32 characters. Send one as Authorization: Bearer <key>.
npx quirepdf-cli keys # list
npx quirepdf-cli keys create ci # create; the secret is printed once
npx quirepdf-cli keys revoke key_h0rRQSKOc8DB
The same through the API:
curl https://api.quirepdf.dev/v1/keys -H "Authorization: Bearer $QUIRE_API_KEY"
{
"keys": [
{ "id": "key_nb6N6M2qmGo7", "prefix": "qk_live_P7W5", "name": "quirepdf-cli on ravi-mbp", "created_at": 1791028361, "last_used_at": 1791028361 },
{ "id": "key_h0rRQSKOc8DB", "prefix": "qk_live_sS2W", "name": "ci", "created_at": 1791028361, "last_used_at": null }
],
"current_key_id": "key_nb6N6M2qmGo7"
}
- Create:
POST /v1/keyswith an optional{"name": "ci"}(up to 60 characters) returns201with the key’s details andapi_key, the secret. It’s shown only in this response. - List:
GET /v1/keysreturns active keys with their prefix, name and timestamps (Unix seconds), never the secret.current_key_idis the key you called with. - Revoke:
DELETE /v1/keys/{id}returns204. The revoked key gets401 unauthorizedfrom then on. You can’t revoke your only active key (409 last_key); create a replacement first.
Use one key per environment or service, so you can revoke one without touching the others.
Plans
| Plan | Renders per month | Price |
|---|---|---|
| Free | 20 | $0 |
| Starter | 2,000 | $19 a month |
| Pro | 10,000 | $49 a month |
| Scale | 50,000 | $129 a month |
Every plan includes every template, the generic layout, PNG previews, the SDKs, the CLI and the MCP server.
- Test renders are free and unlimited. Add
--test(CLI),test: true(SDKs) or?test=true(API) for a watermarked render that never counts and works even after the quota runs out. Use them while you build. - Only successful renders count. A request that fails with any error costs nothing.
- Validation is free.
POST /v1/validatenever counts. - One PDF or one PNG page is one render, whatever its length, up to the 200-page limit.
- Quotas reset at the start of each calendar month, UTC.
- When the quota runs out, renders return
429 quota_exceededuntil the month ends or you upgrade.
Usage
npx quirepdf-cli usage
you@example.com · free plan · 2026-10
██████████████░░░░░░░░░░ 12 / 20 renders (8 left)
curl https://api.quirepdf.dev/v1/usage -H "Authorization: Bearer $QUIRE_API_KEY"
{ "email": "you@example.com", "plan": "free", "period": "2026-10", "used": 24, "limit": 100, "remaining": 76 }
Every successful render also returns x-quota-limit and x-quota-remaining headers, so you can track usage without an extra call.
Upgrade
npx quirepdf-cli upgrade pro
This opens a hosted checkout page for the plan. Through the API, POST /v1/billing/checkout with {"plan": "starter"}, "pro" or "scale" returns {"url": "..."} to send the user to.
Payments are handled by Dodo Payments, our merchant of record. Dodo charges the right sales tax, VAT or GST for your country and issues your invoices. Quire never sees your card details.
Your plan changes as soon as payment completes, and the new limit applies immediately. Renders you’ve already used this month still count, so upgrading mid-month from Free to Starter with 100 used leaves you 1,900.
Manage your subscription
npx quirepdf-cli billing
This opens the billing portal, where you can change plans, cancel, update your card and download invoices. The link works for 24 hours. Through the API, GET /v1/billing/portal returns {"url": "..."}.
- Changing plans: do it in the portal. Starting a second checkout while you have a paid plan returns
409 already_subscribed, so you’re never billed twice. - Cancelling: you keep your paid plan until the end of the period you’ve paid for, then the account returns to the free plan.
- Failed payments: if a renewal payment fails, you keep your plan while the card is retried and you’re emailed. The account returns to the free plan only if the subscription ends.
What Quire stores
| Stored | Not stored |
|---|---|
| Your email address and plan | The data you send to render or validate |
| A SHA-256 hash of each API key, its 12-character prefix, name, and created and last-used times | The PDFs and PNGs Quire produces |
| The number of successful renders per month | Plaintext API keys |
Documents are rendered in memory and returned in the response. Quire doesn’t write your data or the output to disk or keep a copy.
When you sign in, the new key is held so the CLI can collect it, and cleared as soon as it does. A key nobody collects is cleared after 30 minutes. Sign-in links are stored as hashes. Rate limits are counted in memory and keep no history.