Developers and AI assistants
API
Make one-page invoices from code or from an AI assistant: a shareable page with a Pay button and the PDF, or just the PDF. No account and no API key. JSON in; JSON or PDF out.
Machine-readable: /openapi.json (OpenAPI 3.1) · this page as Markdown: /docs/api.md · Agent Skill: SKILL.md
Quick start
Create an invoice behind a share link:
curl -sS https://onepageinvoice.com/api/v1/invoices \
-H 'Content-Type: application/json' \
-d '{
"number": "0042", "date": "2026-11-05", "due_date": "2026-11-19", "currency": "USD",
"from": {"name": "Ada Ferreira", "email": "[email protected]"},
"to": {"name": "Castelo Bakery Lda"},
"items": [{"description": "Site survey and measurements", "quantity": 1, "unit_price": 450}],
"payment_instructions": ["Bank transfer: IBAN PT50 0002 0123 1234 5678 9015 4"]
}'
Response (201 Created):
{
"id": "u2q6m74sticimboa",
"url": "https://onepageinvoice.com/i/u2q6m74sticimboa",
"pdf_url": "https://onepageinvoice.com/i/u2q6m74sticimboa.pdf",
"edit_url": "https://onepageinvoice.com/new#id=u2q6m74sticimboa&token=…",
"edit_token": "…",
"expires_at": "2026-12-05T17:18:22Z"
}
url is the page your client opens: the amount, the PDF, your payment instructions, and a Pay button when you send a payment_url. Add "link": true and/or "qr": true to print the page's address or a QR code to it on the PDF. edit_url opens the invoice in the editor; it's private, like a password. Links expire 30 days after the last change.
Just the PDF, nothing stored:
curl -sS https://onepageinvoice.com/api/v1/pdf -H 'Content-Type: application/json' \
-d @invoice.json -o invoice-0042.pdf
Endpoints
| Method and path | What it does |
|---|---|
POST /api/v1/invoices | Save an invoice; returns its links and the edit token (once). |
GET /api/v1/invoices/{id} | Load it for editing. Needs Authorization: Bearer <edit_token>. |
PUT /api/v1/invoices/{id} | Replace it; same link, expiry restarts. Needs the token. |
DELETE /api/v1/invoices/{id} | Turn the link off and erase the invoice (the page then answers 410). Needs the token. |
POST /api/v1/pdf | Render a PDF; nothing is stored. |
POST /api/v1/preview | Draw a draft as SVG and list problems per field (what the editor uses). |
GET /i/{id}, GET /i/{id}.pdf | The share page and its PDF. |
The invoice
| Field | Type | Notes |
|---|---|---|
number | string | Required, up to 32 characters. |
date, due_date | YYYY-MM-DD | Date required; due date defaults to it. |
currency | string | USD (default), EUR, GBP, CAD, AUD, NZD, CHF, JPY. |
from | object | name (required), address (up to 4 lines), email, phone, website, tax_id, logo (base64 PNG or JPEG, up to 1 MB; Classic prints it). |
to | object | name (required), lines (attention and address, up to 4; note: lines, not address), email. |
items | array | description, quantity (> 0), unit_price (negative = discount). At least one; Classic and Bold fit 15, Minimal 10. |
tax_rate | number | Percent of the net amount, 0–100. |
payment_instructions | array of strings | Up to 4 lines, e.g. bank details. |
payment_url | https URL | Your Stripe, PayPal or bank link: the Pay button. Without one, the share page shows the invoice, the PDF and a button to copy your payment instructions. |
link, qr | booleans | For saved invoices: print the online invoice's address (“Pay online: …”) and/or a QR code that opens it. Independent; both off by default. Without link, a payment_url prints as “Pay online” instead. |
notes | string | Up to four lines on the page. |
template | string | classic (default), minimal, bold. |
accent | #rrggbb | Default #5980a6. |
page_size | string | letter (default) or a4 (use it outside the US and Canada). |
Required: number, date, from.name, to.name and at least one item. Unknown fields are rejected with 400, so a typo never goes unnoticed. To check an invoice without saving anything, send it to POST /api/v1/preview: an empty problems list means it's ready.
Errors and limits
422:{"problems": [{"field": "to.name", "message": "Add a client name…", "missing": true}]}. Fields are JSON paths such asitems.2.unit_price; an empty field means the whole invoice, e.g. it doesn't fit on one page.400malformed JSON or unknown field ·401/403missing or wrong edit token ·404no such invoice ·410link turned off ·413body over 3 MB ·429too many saves (seeRetry-After).- Saves are limited per address (a burst of 30, then about one a minute). Rendering PDFs is not stored and not limited beyond fair use.
For AI assistants
Your users can say “invoice Castelo Bakery for the site survey” and get a link to review. Give your agent these instructions, or install the Agent Skill (save it as .claude/skills/onepageinvoice/SKILL.md).
For AGENTS.md (Codex and other agents):
## Invoices
To make an invoice, use the One Page Invoice API (no key): POST JSON to
https://onepageinvoice.com/api/v1/invoices for a shareable invoice page with a
Pay button and PDF, or to /api/v1/pdf for just a PDF file. Reference:
https://onepageinvoice.com/docs/api.md. Ask for missing sender or client details
instead of inventing them. On 422, fix the listed fields and retry. Show the
user the share link (url), the PDF (pdf_url) and the private edit link
(edit_url); don't claim the invoice was sent.
Rules for agents: create drafts for the user to review and send; never invent amounts, clients or bank details; keep the edit token secret.