Skip to content

REST API

Read your orders, customers and inventory, create orders, and advance stages. Available on Premium and above.

Base URL and authentication

https://yourshop.printersfriend.com/api/v1

Create a token in Insight, then API tokens, and pass it as a bearer token:

bash
curl -H "Authorization: Bearer {token}" \
     -H "Accept: application/json" \
     https://yourshop.printersfriend.com/api/v1/me

Every request is checked for four things: a valid token, an active user, the workspace it belongs to, and whether your plan allows API access. The plan check runs per request, so a downgrade stops access immediately even for existing tokens.

Rate limits

Endpoint groupLimit
Reads60 requests per minute
Writes20 requests per minute

Keyed per user. Throttle your side rather than retrying hard.

Endpoints

MethodPathPurpose
GET/v1/meThe authenticated user
GET/v1/customersList customers
GET/v1/customers/{id}One customer, with contacts
GET/v1/ordersList orders
GET/v1/orders/{order}One order, with lines, stage history, invoices, artwork
POST/v1/ordersCreate an order
POST/v1/orders/{order}/advanceAdvance an order's stage
GET/v1/inventoryList SKUs with stock

GET /v1/customers

Query parameterEffect
searchCase-insensitive name match

Paginated, 50 per page. Each row:

json
{
  "id": 1,
  "name": "Northside Football Club",
  "slug": "northside-fc",
  "price_list": "Club rate",
  "discount": "12.00",
  "orders_count": 4,
  "open_orders": 2
}

GET /v1/customers/

Adds lifetime value, payment terms, default carrier, the full price list and contacts:

json
{
  "id": 1,
  "name": "Northside Football Club",
  "slug": "northside-fc",
  "lifetime_value_cents": 924000,
  "price_list": { "name": "Club rate", "discount_percent": "12.00" },
  "payment_terms": "7 day from invoice",
  "default_carrier": "DHL eParcel",
  "contacts": [
    { "name": "Megan Cole", "email": "megan@northsidefc.au", "phone": "0408 221 559", "is_primary": true }
  ]
}

GET /v1/orders

Query parameterEffect
stageFilter by stage code, for example in_production
customerFilter by customer slug

Paginated, 50 per page.

GET /v1/orders/

The full order: lines with SKUs, stage history, invoices and artwork.

POST /v1/orders

json
{
  "customer_id": 1,
  "due_by": "2026-09-12",
  "notes": "Rush job, confirmed with Megan",
  "lines": [
    { "description": "Gildan 5000 black L, front print 1 colour", "quantity": 120, "unit_price_cents": 1412 }
  ]
}
FieldRules
customer_idRequired. Must be an existing organisation
linesRequired, at least one
lines[].descriptionRequired, up to 255 characters
lines[].quantityRequired, 1 to 10,000
lines[].unit_price_centsRequired, 0 or more
due_byOptional date
notesOptional, up to 2,000 characters

The order is created in the Artwork stage, and tax is applied from your tax scheme.

API orders are priced by you, not by the engine

unit_price_cents is taken as given. The pricing rules that apply to a quote built in the workspace do not re-price an API-created line. If you want engine pricing, build a quote in the workspace and convert it. Use the API for orders whose prices are already decided by the system creating them.

A create that would exceed your plan's open-order limit returns 422 with the reason in message.

POST /v1/orders/{order}/advance

json
{ "to_stage": "in_production" }

to_stage must be a valid stage code. This fires the same side effects as advancing in the workspace: customer comms, stock consumption, webhooks and stage history. It is not a quiet database update.

GET /v1/inventory

Query parameterEffect
lowOnly SKUs at or under their reorder point
searchCase-insensitive code match

Paginated, 100 per page:

json
{
  "code": "GIL-5000-BLK-L",
  "style": "5000 Heavy Cotton Tee",
  "brand": "Gildan",
  "colour": "Black",
  "colour_hex": "#000000",
  "size": "L",
  "on_hand": 145,
  "reserved": 24,
  "available": 121,
  "reorder_point": 60,
  "status": "ok"
}

Errors

CodeMeaning
401Missing or invalid token
403Token valid, but the user is inactive or lacks permission
404Not found, or belongs to another workspace
422Validation failed, or a plan limit was hit. Read message
429Rate limited. Back off

Common integrations

WantUse
Push orders from your own websitePOST /v1/orders
Advance stages from a warehouse systemPOST /v1/orders/{order}/advance
Stock levels on another siteGET /v1/inventory
React to what happens in the shopWebhooks, not polling

For anything event-driven, use webhooks. Polling /v1/orders every minute burns your rate limit and still tells you late.

Printer's Friend - software for apparel print shops