API reference
Send print-ready files and a ship-to address; Quantum prints, binds and ships the order and tells you what happened by webhook.
Every order is paid from your prepaid credit balance when you submit it. Sandbox keys (qp_test_…) work the same way with play credit, and sandbox orders are never printed.
Version 1.0.0-draft.1. Generated from the OpenAPI spec.
Basics
- Base URL
https://api.quantum-production.com/v1- Authentication
Authorization: Bearer qp_live_…orqp_test_…. Create and revoke keys in the dashboard. The mode of the key decides whether you are placing real or sandbox orders.- Format
JSON in and out. Money is an object with an integer
amountin cents and acurrency. Times are ISO 8601 in UTC.- Errors
Every error has the same envelope with a stable
code. See Errors for each code and what to do about it.- Retries
Send an
Idempotency-Keywith every new order. Retrying with the same key and body returns the original order instead of placing another.
Products
The SKUs you have set up in the dashboard.
List your SKUs
GET/v1/products
Any SKU that isn't off can be ordered, with or without a proof first.
Responses
| 200 | Your SKUs. | object |
|---|---|---|
| 401 | The key is missing, malformed, unknown or revoked. | Error |
| 429 | Too many requests. Wait for the number of seconds in | Error |
curl "https://api.quantum-production.com/v1/products" \
-H "Authorization: Bearer $QUANTUM_KEY"const res = await fetch(`https://api.quantum-production.com/v1/products`, {
headers: {
Authorization: `Bearer ${process.env.QUANTUM_KEY}`,
},
});
const data = await res.json();import os
import requests
res = requests.get(
"https://api.quantum-production.com/v1/products",
headers={
"Authorization": f"Bearer {os.environ['QUANTUM_KEY']}",
},
)
data = res.json()Response 200
{
"data": [
{
"sku": "FAMILY-ALBUM-9X9",
"name": "Family album, 9×9 hardcover",
"status": "live",
"family": "hardcover",
"trim": {
"width_in": 9,
"height_in": 9
},
"binding": null,
"cover": "hardcover",
"paper_finish": "matte",
"pages": {
"min": 20,
"max": 160,
"multiple_of": 2
},
"price": {
"base": {
"amount": 360,
"currency": "USD"
},
"per_page": {
"amount": 16,
"currency": "USD"
}
}
}
]
}Brands
The names your parcels ship under, set up in the dashboard.
List your brands
GET/v1/brands
Your active brands, the default first. Send a brand's id as brand on an order to put its ship-from name on the label; orders without one use your default brand.
Responses
| 200 | Your brands. | object |
|---|---|---|
| 401 | The key is missing, malformed, unknown or revoked. | Error |
| 429 | Too many requests. Wait for the number of seconds in | Error |
curl "https://api.quantum-production.com/v1/brands" \
-H "Authorization: Bearer $QUANTUM_KEY"const res = await fetch(`https://api.quantum-production.com/v1/brands`, {
headers: {
Authorization: `Bearer ${process.env.QUANTUM_KEY}`,
},
});
const data = await res.json();import os
import requests
res = requests.get(
"https://api.quantum-production.com/v1/brands",
headers={
"Authorization": f"Bearer {os.environ['QUANTUM_KEY']}",
},
)
data = res.json()Response 200
{
"data": [
{
"id": "9a4e2b7c-1d3f-4a5b-8c6d-2e1f0a9b8c7d",
"name": "Acme Books",
"is_default": true,
"ship_from": {
"name": "Acme Books",
"company": "Acme Publishing LLC",
"phone": "609-555-0100"
},
"return_address": {
"name": "Acme Books",
"company": "Acme Publishing LLC",
"line1": "12 Orchard Lane",
"city": "Princeton",
"state": "NJ",
"postal_code": "08540",
"country": "US",
"phone": "609-555-0100"
}
}
]
}Orders
Price, place, track, change and cancel orders.
Price an order without placing it
POST/v1/orders/estimate
Returns exactly what POST /orders would charge right now. Nothing is held or charged.
Request body
OrderRequest. ship_to is required unless proof is true.
| Field | Type | Description |
|---|---|---|
external_id | string | Your own order id. Returned on the order and in every webhook. Up to 50 characters. |
brand | string (uuid) | The brand to ship under, by its |
proof | boolean | Make this a proof order: one copy of one SKU, shipped to the brand's address (your default brand unless you send Defaults to false. |
shipping_methodrequired | string | - One of |
ship_to | Address | |
itemsrequired | array of OrderItemRequest | 1 to 50 items. |
Responses
| 200 | The price. | Estimate |
|---|---|---|
| 400 | The request is malformed or fails validation. | Error |
| 401 | The key is missing, malformed, unknown or revoked. | Error |
| 403 | The key can't do this ( | Error |
| 422 | The request is well formed but can't be fulfilled, such as an unknown SKU or an unreachable file. | Error |
| 429 | Too many requests. Wait for the number of seconds in | Error |
curl -X POST "https://api.quantum-production.com/v1/orders/estimate" \
-H "Authorization: Bearer $QUANTUM_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_id": "1042",
"shipping_method": "standard",
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"items": [
{
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40,
"interior_url": "https://files.example.com/1042/interior.pdf",
"cover_url": "https://files.example.com/1042/cover.pdf"
}
]
}'const res = await fetch(`https://api.quantum-production.com/v1/orders/estimate`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.QUANTUM_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"external_id": "1042",
"shipping_method": "standard",
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"items": [
{
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40,
"interior_url": "https://files.example.com/1042/interior.pdf",
"cover_url": "https://files.example.com/1042/cover.pdf"
}
]
}),
});
const data = await res.json();import os
import requests
res = requests.post(
"https://api.quantum-production.com/v1/orders/estimate",
headers={
"Authorization": f"Bearer {os.environ['QUANTUM_KEY']}",
},
json={
"external_id": "1042",
"shipping_method": "standard",
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US",
},
"items": [
{
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40,
"interior_url": "https://files.example.com/1042/interior.pdf",
"cover_url": "https://files.example.com/1042/cover.pdf",
},
],
},
)
data = res.json()Response 200
{
"charges": {
"items": {
"amount": 1000,
"currency": "USD"
},
"discount": {
"amount": 0,
"currency": "USD"
},
"handling": {
"amount": 150,
"currency": "USD"
},
"shipping": {
"amount": 595,
"currency": "USD"
},
"tax": {
"amount": 0,
"currency": "USD"
},
"total": {
"amount": 1745,
"currency": "USD"
}
},
"shipping_is_estimate": true,
"balance_after": {
"amount": 48255,
"currency": "USD"
}
}List orders, newest first
GET/v1/orders
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
status | query | OrderStatus | |
brand | query | string (uuid) | Only orders under this brand (a brand |
created_after | query | string (date-time) | |
created_before | query | string (date-time) | |
limit | query | integer | 1 to 100. Defaults to 25. |
cursor | query | string | The |
Responses
| 200 | A page of orders. | object |
|---|---|---|
| 400 | The request is malformed or fails validation. | Error |
| 401 | The key is missing, malformed, unknown or revoked. | Error |
| 429 | Too many requests. Wait for the number of seconds in | Error |
curl "https://api.quantum-production.com/v1/orders?status=shipped&limit=25" \
-H "Authorization: Bearer $QUANTUM_KEY"const res = await fetch(`https://api.quantum-production.com/v1/orders?status=shipped&limit=25`, {
headers: {
Authorization: `Bearer ${process.env.QUANTUM_KEY}`,
},
});
const data = await res.json();import os
import requests
res = requests.get(
"https://api.quantum-production.com/v1/orders",
headers={
"Authorization": f"Bearer {os.environ['QUANTUM_KEY']}",
},
params={
"status": "shipped",
"limit": "25",
},
)
data = res.json()Response 200
{
"data": [
{
"id": "6f2d4c1e-8a3b-4e5f-9c7d-1b2a3c4d5e6f",
"external_id": "1042",
"mode": "live",
"proof": false,
"brand": {
"id": "9a4e2b7c-1d3f-4a5b-8c6d-2e1f0a9b8c7d",
"name": "Acme Books"
},
"status": "shipped",
"status_reason": null,
"status_history": [
{
"status": "received",
"at": "2026-10-13T15:04:05.000Z"
},
{
"status": "in_production",
"at": "2026-10-14T09:12:40.000Z"
},
{
"status": "shipped",
"at": "2026-10-15T16:47:22.000Z"
}
],
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"shipping": {
"method": "standard",
"carrier": "UPS",
"tracking_numbers": [
"1Z4A6E290312345678"
],
"shipped_at": "2026-10-15T16:47:22.000Z"
},
"items": [
{
"item_id": null,
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40
}
],
"charges": {
"items": {
"amount": 1000,
"currency": "USD"
},
"discount": {
"amount": 0,
"currency": "USD"
},
"handling": {
"amount": 150,
"currency": "USD"
},
"shipping": {
"amount": 595,
"currency": "USD"
},
"tax": {
"amount": 0,
"currency": "USD"
},
"total": {
"amount": 1745,
"currency": "USD"
}
},
"ledger": [
{
"type": "order_charge",
"amount": {
"amount": -1745,
"currency": "USD"
},
"at": "2026-10-13T15:04:05.000Z"
}
],
"created_at": "2026-10-13T15:04:05.000Z",
"updated_at": "2026-10-15T16:47:22.000Z"
}
],
"next_cursor": null
}Place an order
POST/v1/orders
Charges the full price to your credit balance and returns the order with status received. If your balance is too low the order is refused with 402 insufficient_credit; nothing is charged.
Send a unique Idempotency-Key with every new order. Retrying with the same key and the same body returns the original order instead of placing a second one. The same key with a different body is refused with 409 idempotency_conflict.
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Keyrequired | header | string | Any unique string up to 255 characters; a UUID works well. Up to 255 characters. |
Request body
OrderRequest. ship_to is required unless proof is true.
| Field | Type | Description |
|---|---|---|
external_id | string | Your own order id. Returned on the order and in every webhook. Up to 50 characters. |
brand | string (uuid) | The brand to ship under, by its |
proof | boolean | Make this a proof order: one copy of one SKU, shipped to the brand's address (your default brand unless you send Defaults to false. |
shipping_methodrequired | string | - One of |
ship_to | Address | |
itemsrequired | array of OrderItemRequest | 1 to 50 items. |
Responses
| 200 | A retry with an Idempotency-Key already used; the original order. | Order |
|---|---|---|
| 201 | Order placed and charged. | Order |
| 400 | The request is malformed or fails validation. | Error |
| 401 | The key is missing, malformed, unknown or revoked. | Error |
| 402 | Your balance doesn't cover the charge. | Error |
| 403 | The key can't do this ( | Error |
| 409 | The order isn't in a state that allows this, or the Idempotency-Key was reused with a different body. | Error |
| 422 | The request is well formed but can't be fulfilled, such as an unknown SKU or an unreachable file. | Error |
| 429 | Too many requests. Wait for the number of seconds in | Error |
curl -X POST "https://api.quantum-production.com/v1/orders" \
-H "Authorization: Bearer $QUANTUM_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"external_id": "1042",
"shipping_method": "standard",
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"items": [
{
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40,
"interior_url": "https://files.example.com/1042/interior.pdf",
"cover_url": "https://files.example.com/1042/cover.pdf"
}
]
}'const res = await fetch(`https://api.quantum-production.com/v1/orders`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.QUANTUM_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"external_id": "1042",
"shipping_method": "standard",
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"items": [
{
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40,
"interior_url": "https://files.example.com/1042/interior.pdf",
"cover_url": "https://files.example.com/1042/cover.pdf"
}
]
}),
});
const data = await res.json();import os
import uuid
import requests
res = requests.post(
"https://api.quantum-production.com/v1/orders",
headers={
"Authorization": f"Bearer {os.environ['QUANTUM_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"external_id": "1042",
"shipping_method": "standard",
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US",
},
"items": [
{
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40,
"interior_url": "https://files.example.com/1042/interior.pdf",
"cover_url": "https://files.example.com/1042/cover.pdf",
},
],
},
)
data = res.json()Response 201
{
"id": "6f2d4c1e-8a3b-4e5f-9c7d-1b2a3c4d5e6f",
"external_id": "1042",
"mode": "live",
"proof": false,
"brand": {
"id": "9a4e2b7c-1d3f-4a5b-8c6d-2e1f0a9b8c7d",
"name": "Acme Books"
},
"status": "received",
"status_reason": null,
"status_history": [
{
"status": "received",
"at": "2026-10-13T15:04:05.000Z"
}
],
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"shipping": {
"method": "standard",
"carrier": null,
"tracking_numbers": [],
"shipped_at": null
},
"items": [
{
"item_id": null,
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40
}
],
"charges": {
"items": {
"amount": 1000,
"currency": "USD"
},
"discount": {
"amount": 0,
"currency": "USD"
},
"handling": {
"amount": 150,
"currency": "USD"
},
"shipping": {
"amount": 595,
"currency": "USD"
},
"tax": {
"amount": 0,
"currency": "USD"
},
"total": {
"amount": 1745,
"currency": "USD"
}
},
"ledger": [
{
"type": "order_charge",
"amount": {
"amount": -1745,
"currency": "USD"
},
"at": "2026-10-13T15:04:05.000Z"
}
],
"created_at": "2026-10-13T15:04:05.000Z",
"updated_at": "2026-10-13T15:04:05.000Z"
}Get one order with its status history, tracking and charges
GET/v1/orders/{order_id}
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
order_idrequired | path | string (uuid) |
Responses
| 200 | The order. | Order |
|---|---|---|
| 401 | The key is missing, malformed, unknown or revoked. | Error |
| 404 | No such order for this key's account and mode. | Error |
| 429 | Too many requests. Wait for the number of seconds in | Error |
curl "https://api.quantum-production.com/v1/orders/$ORDER_ID" \
-H "Authorization: Bearer $QUANTUM_KEY"const res = await fetch(`https://api.quantum-production.com/v1/orders/${orderId}`, {
headers: {
Authorization: `Bearer ${process.env.QUANTUM_KEY}`,
},
});
const data = await res.json();import os
import requests
res = requests.get(
f"https://api.quantum-production.com/v1/orders/{order_id}",
headers={
"Authorization": f"Bearer {os.environ['QUANTUM_KEY']}",
},
)
data = res.json()Response 200
{
"id": "6f2d4c1e-8a3b-4e5f-9c7d-1b2a3c4d5e6f",
"external_id": "1042",
"mode": "live",
"proof": false,
"brand": {
"id": "9a4e2b7c-1d3f-4a5b-8c6d-2e1f0a9b8c7d",
"name": "Acme Books"
},
"status": "shipped",
"status_reason": null,
"status_history": [
{
"status": "received",
"at": "2026-10-13T15:04:05.000Z"
},
{
"status": "in_production",
"at": "2026-10-14T09:12:40.000Z"
},
{
"status": "shipped",
"at": "2026-10-15T16:47:22.000Z"
}
],
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"shipping": {
"method": "standard",
"carrier": "UPS",
"tracking_numbers": [
"1Z4A6E290312345678"
],
"shipped_at": "2026-10-15T16:47:22.000Z"
},
"items": [
{
"item_id": null,
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40
}
],
"charges": {
"items": {
"amount": 1000,
"currency": "USD"
},
"discount": {
"amount": 0,
"currency": "USD"
},
"handling": {
"amount": 150,
"currency": "USD"
},
"shipping": {
"amount": 595,
"currency": "USD"
},
"tax": {
"amount": 0,
"currency": "USD"
},
"total": {
"amount": 1745,
"currency": "USD"
}
},
"ledger": [
{
"type": "order_charge",
"amount": {
"amount": -1745,
"currency": "USD"
},
"at": "2026-10-13T15:04:05.000Z"
}
],
"created_at": "2026-10-13T15:04:05.000Z",
"updated_at": "2026-10-15T16:47:22.000Z"
}Cancel an order and get its full charge back as credit
POST/v1/orders/{order_id}/cancel
Works until the order goes into production. After that it returns 409 order_not_cancellable.
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
order_idrequired | path | string (uuid) |
Request body (optional)
| Field | Type | Description |
|---|---|---|
reason | string | Up to 500 characters. |
Responses
| 200 | Cancelled. The order now has status | Order |
|---|---|---|
| 400 | The request is malformed or fails validation. | Error |
| 401 | The key is missing, malformed, unknown or revoked. | Error |
| 403 | The key can't do this ( | Error |
| 404 | No such order for this key's account and mode. | Error |
| 409 | The order isn't in a state that allows this, or the Idempotency-Key was reused with a different body. | Error |
| 429 | Too many requests. Wait for the number of seconds in | Error |
curl -X POST "https://api.quantum-production.com/v1/orders/$ORDER_ID/cancel" \
-H "Authorization: Bearer $QUANTUM_KEY" \
-H "Content-Type: application/json" \
-d '{
"reason": "Customer changed their mind"
}'const res = await fetch(`https://api.quantum-production.com/v1/orders/${orderId}/cancel`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.QUANTUM_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"reason": "Customer changed their mind"
}),
});
const data = await res.json();import os
import requests
res = requests.post(
f"https://api.quantum-production.com/v1/orders/{order_id}/cancel",
headers={
"Authorization": f"Bearer {os.environ['QUANTUM_KEY']}",
},
json={
"reason": "Customer changed their mind",
},
)
data = res.json()Response 200
{
"id": "6f2d4c1e-8a3b-4e5f-9c7d-1b2a3c4d5e6f",
"external_id": "1042",
"mode": "live",
"proof": false,
"brand": {
"id": "9a4e2b7c-1d3f-4a5b-8c6d-2e1f0a9b8c7d",
"name": "Acme Books"
},
"status": "cancelled",
"status_reason": "Customer changed their mind",
"status_history": [
{
"status": "received",
"at": "2026-10-13T15:04:05.000Z"
},
{
"status": "cancelled",
"at": "2026-10-13T15:20:00.000Z"
}
],
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"shipping": {
"method": "standard",
"carrier": null,
"tracking_numbers": [],
"shipped_at": null
},
"items": [
{
"item_id": null,
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40
}
],
"charges": {
"items": {
"amount": 1000,
"currency": "USD"
},
"discount": {
"amount": 0,
"currency": "USD"
},
"handling": {
"amount": 150,
"currency": "USD"
},
"shipping": {
"amount": 595,
"currency": "USD"
},
"tax": {
"amount": 0,
"currency": "USD"
},
"total": {
"amount": 1745,
"currency": "USD"
}
},
"ledger": [
{
"type": "order_charge",
"amount": {
"amount": -1745,
"currency": "USD"
},
"at": "2026-10-13T15:04:05.000Z"
},
{
"type": "cancel_refund",
"amount": {
"amount": 1745,
"currency": "USD"
},
"at": "2026-10-13T15:20:00.000Z"
}
],
"created_at": "2026-10-13T15:04:05.000Z",
"updated_at": "2026-10-13T15:20:00.000Z"
}Change where an order ships
PATCH/v1/orders/{order_id}/shipping-address
Works until the shipping label prints; after that it returns 409 address_not_editable. Shipping is re-estimated, and any difference is charged or credited.
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
order_idrequired | path | string (uuid) |
Request body
| Field | Type | Description |
|---|---|---|
ship_torequired | Address |
Responses
| 200 | Updated. | Order |
|---|---|---|
| 400 | The request is malformed or fails validation. | Error |
| 401 | The key is missing, malformed, unknown or revoked. | Error |
| 402 | Your balance doesn't cover the charge. | Error |
| 403 | The key can't do this ( | Error |
| 404 | No such order for this key's account and mode. | Error |
| 409 | The order isn't in a state that allows this, or the Idempotency-Key was reused with a different body. | Error |
| 422 | The request is well formed but can't be fulfilled, such as an unknown SKU or an unreachable file. | Error |
| 429 | Too many requests. Wait for the number of seconds in | Error |
curl -X PATCH "https://api.quantum-production.com/v1/orders/$ORDER_ID/shipping-address" \
-H "Authorization: Bearer $QUANTUM_KEY" \
-H "Content-Type: application/json" \
-d '{
"ship_to": {
"name": "Ada Lovelace",
"line1": "400 Walnut St",
"line2": "Apt 5",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
}
}'const res = await fetch(`https://api.quantum-production.com/v1/orders/${orderId}/shipping-address`, {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.QUANTUM_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"ship_to": {
"name": "Ada Lovelace",
"line1": "400 Walnut St",
"line2": "Apt 5",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
}
}),
});
const data = await res.json();import os
import requests
res = requests.patch(
f"https://api.quantum-production.com/v1/orders/{order_id}/shipping-address",
headers={
"Authorization": f"Bearer {os.environ['QUANTUM_KEY']}",
},
json={
"ship_to": {
"name": "Ada Lovelace",
"line1": "400 Walnut St",
"line2": "Apt 5",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US",
},
},
)
data = res.json()Response 200
{
"id": "6f2d4c1e-8a3b-4e5f-9c7d-1b2a3c4d5e6f",
"external_id": "1042",
"mode": "live",
"proof": false,
"brand": {
"id": "9a4e2b7c-1d3f-4a5b-8c6d-2e1f0a9b8c7d",
"name": "Acme Books"
},
"status": "received",
"status_reason": null,
"status_history": [
{
"status": "received",
"at": "2026-10-13T15:04:05.000Z"
}
],
"ship_to": {
"name": "Ada Lovelace",
"line1": "400 Walnut St",
"line2": "Apt 5",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"shipping": {
"method": "standard",
"carrier": null,
"tracking_numbers": [],
"shipped_at": null
},
"items": [
{
"item_id": null,
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40
}
],
"charges": {
"items": {
"amount": 1000,
"currency": "USD"
},
"discount": {
"amount": 0,
"currency": "USD"
},
"handling": {
"amount": 150,
"currency": "USD"
},
"shipping": {
"amount": 595,
"currency": "USD"
},
"tax": {
"amount": 0,
"currency": "USD"
},
"total": {
"amount": 1745,
"currency": "USD"
}
},
"ledger": [
{
"type": "order_charge",
"amount": {
"amount": -1745,
"currency": "USD"
},
"at": "2026-10-13T15:04:05.000Z"
}
],
"created_at": "2026-10-13T15:04:05.000Z",
"updated_at": "2026-10-13T15:04:05.000Z"
}Balance
Your credit balance.
Your credit balance for the mode of the key you used
GET/v1/balance
Responses
| 200 | Balance. | Balance |
|---|---|---|
| 401 | The key is missing, malformed, unknown or revoked. | Error |
| 429 | Too many requests. Wait for the number of seconds in | Error |
curl "https://api.quantum-production.com/v1/balance" \
-H "Authorization: Bearer $QUANTUM_KEY"const res = await fetch(`https://api.quantum-production.com/v1/balance`, {
headers: {
Authorization: `Bearer ${process.env.QUANTUM_KEY}`,
},
});
const data = await res.json();import os
import requests
res = requests.get(
"https://api.quantum-production.com/v1/balance",
headers={
"Authorization": f"Bearer {os.environ['QUANTUM_KEY']}",
},
)
data = res.json()Response 200
{
"mode": "live",
"available": {
"amount": 50000,
"currency": "USD"
},
"expiring_soon": {
"amount": 0,
"currency": "USD"
},
"next_expiry_at": "2027-10-13T15:04:05.000Z",
"plan": "starter",
"account_status": "active"
}Sandbox
Tools that only work with a sandbox key.
Move a sandbox order to its next status now
POST/v1/sandbox/orders/{order_id}/advance
Sandbox orders move on their own on a short timer. Use this to step through statuses and webhooks while you build. Without to, an order moves received → in_production → shipped (with a made-up carrier and tracking number). Pass to to jump forward, or to needs_attention, cancelled or rejected; cancelled and rejected orders get their charge back as credit. Orders can't move backwards or leave shipped, cancelled or rejected: that is 409 invalid_status_transition. Live keys get 403 sandbox_only.
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
order_idrequired | path | string (uuid) |
Request body (optional)
| Field | Type | Description |
|---|---|---|
to | OrderStatus |
Responses
| 200 | The order after the change. | Order |
|---|---|---|
| 401 | The key is missing, malformed, unknown or revoked. | Error |
| 403 | The key can't do this ( | Error |
| 404 | No such order for this key's account and mode. | Error |
| 409 | The order isn't in a state that allows this, or the Idempotency-Key was reused with a different body. | Error |
curl -X POST "https://api.quantum-production.com/v1/sandbox/orders/$ORDER_ID/advance" \
-H "Authorization: Bearer $QUANTUM_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "shipped"
}'const res = await fetch(`https://api.quantum-production.com/v1/sandbox/orders/${orderId}/advance`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.QUANTUM_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"to": "shipped"
}),
});
const data = await res.json();import os
import requests
res = requests.post(
f"https://api.quantum-production.com/v1/sandbox/orders/{order_id}/advance",
headers={
"Authorization": f"Bearer {os.environ['QUANTUM_KEY']}",
},
json={
"to": "shipped",
},
)
data = res.json()Response 200
{
"id": "6f2d4c1e-8a3b-4e5f-9c7d-1b2a3c4d5e6f",
"external_id": "1042",
"mode": "sandbox",
"proof": false,
"brand": {
"id": "9a4e2b7c-1d3f-4a5b-8c6d-2e1f0a9b8c7d",
"name": "Acme Books"
},
"status": "shipped",
"status_reason": null,
"status_history": [
{
"status": "received",
"at": "2026-10-13T15:04:05.000Z"
},
{
"status": "in_production",
"at": "2026-10-14T09:12:40.000Z"
},
{
"status": "shipped",
"at": "2026-10-15T16:47:22.000Z"
}
],
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"shipping": {
"method": "standard",
"carrier": "UPS",
"tracking_numbers": [
"1ZQSANDBOX6F2D4C1E"
],
"shipped_at": "2026-10-15T16:47:22.000Z"
},
"items": [
{
"item_id": null,
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40
}
],
"charges": {
"items": {
"amount": 1000,
"currency": "USD"
},
"discount": {
"amount": 0,
"currency": "USD"
},
"handling": {
"amount": 150,
"currency": "USD"
},
"shipping": {
"amount": 595,
"currency": "USD"
},
"tax": {
"amount": 0,
"currency": "USD"
},
"total": {
"amount": 1745,
"currency": "USD"
}
},
"ledger": [
{
"type": "order_charge",
"amount": {
"amount": -1745,
"currency": "USD"
},
"at": "2026-10-13T15:04:05.000Z"
}
],
"created_at": "2026-10-13T15:04:05.000Z",
"updated_at": "2026-10-15T16:47:22.000Z"
}Webhooks
Quantum calls you. How to check the signature, retries and the order of events are in Order statuses and webhooks.
An order event, sent to the webhook URL you set in the dashboard
POSTyour webhook URL
Respond with any 2xx within 10 seconds; do the work afterwards. Anything else is retried with backoff for 24 hours. Delivery is at least once, so deduplicate on id.
Check the Quantum-Signature header before trusting the body. It looks like t=1790000000,v1=5f2c…: v1 is the hex HMAC-SHA256 of <t>.<raw body> keyed with your webhook secret. Compare in constant time, and reject a t more than 5 minutes from now. During a secret rotation the header can carry two v1 values; accept either.
Headers
| Parameter | In | Type | Description |
|---|---|---|---|
Quantum-Signaturerequired | header | string |
Body
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | Unique per event and the same on every retry of it. Deduplicate on this. |
typerequired | EventType | |
created_atrequired | string (date-time) | |
moderequired | string | One of |
datarequired | object | |
data.orderrequired | Order |
Example event
{
"id": "0b8e7f4a-2c1d-4e3f-8a9b-7c6d5e4f3a2b",
"type": "order.shipped",
"created_at": "2026-10-15T16:47:22.000Z",
"mode": "live",
"data": {
"order": {
"id": "6f2d4c1e-8a3b-4e5f-9c7d-1b2a3c4d5e6f",
"external_id": "1042",
"mode": "live",
"proof": false,
"brand": {
"id": "9a4e2b7c-1d3f-4a5b-8c6d-2e1f0a9b8c7d",
"name": "Acme Books"
},
"status": "shipped",
"status_reason": null,
"status_history": [
{
"status": "received",
"at": "2026-10-13T15:04:05.000Z"
},
{
"status": "in_production",
"at": "2026-10-14T09:12:40.000Z"
},
{
"status": "shipped",
"at": "2026-10-15T16:47:22.000Z"
}
],
"ship_to": {
"name": "Ada Lovelace",
"line1": "12 Market St",
"city": "Philadelphia",
"state": "PA",
"postal_code": "19106",
"country": "US"
},
"shipping": {
"method": "standard",
"carrier": "UPS",
"tracking_numbers": [
"1Z4A6E290312345678"
],
"shipped_at": "2026-10-15T16:47:22.000Z"
},
"items": [
{
"item_id": null,
"sku": "FAMILY-ALBUM-9X9",
"quantity": 1,
"page_count": 40
}
],
"charges": {
"items": {
"amount": 1000,
"currency": "USD"
},
"discount": {
"amount": 0,
"currency": "USD"
},
"handling": {
"amount": 150,
"currency": "USD"
},
"shipping": {
"amount": 595,
"currency": "USD"
},
"tax": {
"amount": 0,
"currency": "USD"
},
"total": {
"amount": 1745,
"currency": "USD"
}
},
"ledger": [
{
"type": "order_charge",
"amount": {
"amount": -1745,
"currency": "USD"
},
"at": "2026-10-13T15:04:05.000Z"
}
],
"created_at": "2026-10-13T15:04:05.000Z",
"updated_at": "2026-10-15T16:47:22.000Z"
}
}
}Objects
Money
An amount in the smallest unit of the currency (cents for USD).
| Field | Type | Description |
|---|---|---|
amountrequired | integer | |
currencyrequired | string | One of |
Product
| Field | Type | Description |
|---|---|---|
skurequired | string | What you send in |
namerequired | string | |
statusrequired | string | One of |
familyrequired | string | One of |
trimrequired | object | |
trim.width_inrequired | number | |
trim.height_inrequired | number | |
binding | string or null | |
cover | string or null | |
paper_finish | string or null | |
pagesrequired | object | |
pages.minrequired | integer | |
pages.maxrequired | integer | |
pages.multiple_ofrequired | integer | |
pricerequired | object | Your price per copy at your current plan, before the per-order handling fee, shipping and tax. |
price.baserequired | Money | |
price.per_pagerequired | Money |
Address
| Field | Type | Description |
|---|---|---|
namerequired | string | Up to 100 characters. |
company | string | Up to 100 characters. |
line1required | string | Up to 100 characters. |
line2 | string | Up to 100 characters. |
line3 | string | Up to 100 characters. |
cityrequired | string | Up to 100 characters. |
state | string | State, province or region. Up to 100 characters. |
postal_coderequired | string | Up to 20 characters. |
countryrequired | string | ISO 3166-1 alpha-2. Quantum ships to the US and Canada only. One of |
phone | string | Up to 50 characters. |
email | string (email) | Up to 50 characters. |
OrderItemRequest
| Field | Type | Description |
|---|---|---|
item_id | string | Your own id for this line, echoed back on the order and in webhooks. Up to 50 characters. |
skurequired | string | |
quantityrequired | integer | At least 1. |
page_countrequired | integer | At least 1. |
interior_urlrequired | string (URL) | HTTPS link to the print-ready interior PDF. |
cover_url | string (URL) | HTTPS link to the print-ready cover PDF. Required for books, journals and notebooks, which print their cover separately; refused with |
OrderRequest
ship_to is required unless proof is true.
| Field | Type | Description |
|---|---|---|
external_id | string | Your own order id. Returned on the order and in every webhook. Up to 50 characters. |
brand | string (uuid) | The brand to ship under, by its |
proof | boolean | Make this a proof order: one copy of one SKU, shipped to the brand's address (your default brand unless you send Defaults to false. |
shipping_methodrequired | string | - One of |
ship_to | Address | |
itemsrequired | array of OrderItemRequest | 1 to 50 items. |
Brand
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
namerequired | string | Your own name for the brand; it isn't printed. |
is_defaultrequired | boolean | Orders without a |
ship_fromrequired | object | What the label shows, above Quantum's facility address. |
ship_from.namerequired | string | |
ship_from.companyrequired | string or null | |
ship_from.phonerequired | string or null | |
return_addressrequired | Address | Where the brand's proofs ship. |
BrandRef
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
namerequired | string |
Charges
Estimate
OrderStatus
received → in_production → shipped. An order can also end cancelled or rejected, or stop at needs_attention until Quantum or you fix the problem in status_reason.
received in_production shipped needs_attention cancelled rejected
LedgerLine
| Field | Type | Description |
|---|---|---|
typerequired | string | One of |
amountrequired | Money | Negative for a charge, positive for credit back. |
atrequired | string (date-time) |
Order
| Field | Type | Description |
|---|---|---|
idrequired | string (uuid) | |
external_idrequired | string or null | |
moderequired | string | One of |
proofrequired | boolean | |
brandrequired | any | The brand the order ships under; null only on orders placed before brands existed. |
statusrequired | OrderStatus | |
status_reasonrequired | string or null | |
status_historyrequired | array of objects | |
status_history[].statusrequired | OrderStatus | |
status_history[].atrequired | string (date-time) | |
ship_torequired | Address | |
shippingrequired | object | |
shipping.methodrequired | string | One of |
shipping.carrierrequired | string or null | |
shipping.tracking_numbersrequired | array of string | |
shipping.shipped_atrequired | string (date-time) or null | |
itemsrequired | array of objects | |
items[].item_idrequired | string or null | |
items[].skurequired | string | |
items[].quantityrequired | integer | |
items[].page_countrequired | integer | |
chargesrequired | Charges | |
ledgerrequired | array of LedgerLine | |
created_atrequired | string (date-time) | |
updated_atrequired | string (date-time) |
Balance
| Field | Type | Description |
|---|---|---|
moderequired | string | One of |
availablerequired | Money | |
expiring_soonrequired | Money | Credit that expires within 30 days. |
next_expiry_atrequired | string (date-time) or null | When the soonest-expiring credit expires, if there is any. |
planrequired | string | One of |
account_statusrequired | string | One of |
EventType
order.received order.in_production order.shipped order.needs_attention order.cancelled order.rejected
Event
ErrorCode
Stable and machine-readable; branch on this, never on message.
invalid_request unauthorized forbidden account_suspended sandbox_only not_found insufficient_credit idempotency_conflict sku_not_found sku_not_orderable proof_required page_count_out_of_range file_unreachable shipping_method_unavailable order_not_cancellable address_not_editable invalid_status_transition rate_limited internal_error service_unavailable
Error
| Field | Type | Description |
|---|---|---|
errorrequired | object | |
error.coderequired | ErrorCode | |
error.messagerequired | string | For people. The wording can change. |
error.fieldrequired | string or null | The request field at fault, as a JSON path such as |
error.docs_urlrequired | string (URL) | |
error.retryablerequired | boolean | Whether the same request might succeed later. |
error.request_idrequired | string | |
error.details | object | Extra facts for some codes, such as |
