Developer documentation
PrinterFlo API reference
The PrinterFlo REST API gives you programmatic access to your shop's jobs, customers, invoices, and payments. It powers our Zapier integration and is available to every PrinterFlo account at no extra cost.
Base URL
https://app.printerflo.com/api/v1
All requests and responses are JSON. All timestamps are ISO-8601 with
timezone (e.g. 2026-07-12T09:20:08.548+00:00).
Money is in integer cents with a currency field.
Authentication
Create an API key in PrinterFlo under Settings → API & Zapier.
Keys look like pfl_live_… and are shown once
at creation. Send the key as a bearer token on every request:
curl https://app.printerflo.com/api/v1/me \
-H "Authorization: Bearer pfl_live_YOUR_KEY"
Missing, unknown, or revoked keys get 401
with { "error": "Invalid or missing API key." }.
Every key is scoped to one shop; you only ever see your own data. Keys can
be revoked any time from the same settings screen.
Rate limits
120 requests per minute per key. Exceeding it returns
429 with a
Retry-After: 60 header — back off and retry.
Common parameters
?limit=— page size, default 50, max 100. Results are newest-first.?since=— ISO-8601 timestamp; only records created at/after it (ideal for polling).
Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | /me | Verify a key; returns your shop |
| GET | /jobs | List orders & quotes |
| POST | /jobs | Create a quote |
| GET | /customers | List / search customers |
| POST | /customers | Find-or-create a customer |
| GET | /invoices | List invoices |
| GET | /payments | List payments |
GET /me
The cheapest auth check. Returns the shop the key belongs to.
{ "org": { "id": "…", "name": "Demo Shop", "currency": "cad" } } GET /jobs
Orders and quotes, newest first. Filters:
?kind=
(quote or
sales_order),
?status= (your shop's own stage names),
?since=, and
?updated_since= (records updated at/after
a timestamp — how our Zapier order-status trigger polls).
{
"jobs": [
{
"id": "…",
"number": 42,
"title": "Banner 3ft x 6ft",
"kind": "sales_order",
"status": "processing",
"source": "staff",
"po_number": null,
"total_cents": 36160,
"currency": "cad",
"created_at": "2026-07-12T09:20:08+00:00",
"updated_at": "2026-07-12T10:27:06+00:00",
"customer": { "id": "…", "name": "Reid Auto Group", "company": null, "email": "…", "phone": "…" },
"url": "https://app.printerflo.com/jobs/…"
}
]
} POST /jobs
Creates a quote — the safe entry point for automations: your shop
prices and confirms it before anything is billed or produced. The customer is
deduped by email within your shop. Returns 201
with the created job.
POST /api/v1/jobs
{
"title": "Storefront window decals", // required
"description": "From website lead form", // optional
"po_number": "PO-1234", // optional
"customer": {
"name": "Jane Smith", // required
"email": "jane@example.com", // used for dedupe
"phone": "555-0101",
"company": "Smith Realty"
}
} GET /customers
Filters: ?email= (exact match,
case-insensitive), ?q= (searches
name, company, and email), ?since=.
Returns id, name, company, email, phone,
payment_terms, created_at.
POST /customers
Find-or-create by email: if a customer with the given email exists, it's
returned with "existing": true
instead of creating a duplicate. Body:
name (required),
email,
phone,
company,
notes.
{ "customer": { "id": "…", "name": "Jane Smith", … }, "existing": false } GET /invoices
Filters: ?status=,
?since=. Each invoice includes
its totals in cents (subtotal_cents, tax_cents,
discount_cents, total_cents, amount_paid_cents), dates
(issued_at, due_date, created_at), and the
linked job and
customer.
GET /payments
Filter: ?since=. Each payment has
amount_cents, currency, method
(e.g. stripe, cash, cheque, terminal),
reference, paid_at, created_at, and the
linked job with its customer.
Errors
400— invalid input; body is{ "error": "…" }explaining what's wrong.401— missing, unknown, or revoked API key.429— rate limit exceeded; retry after theRetry-Afterseconds.
Questions or a missing endpoint?
Email support@printerflo.com — we typically reply within one business day. Prefer no-code? The same API powers our Zapier integration.