Quickstart

From a sandbox key to a shipped sandbox order and its webhooks in about ten minutes. Sandbox orders go through every status but are never printed, and they're paid from play credit.

1. Create a sandbox key

In the dashboard, open API keys and create a sandbox key. It starts qp_test_ and is shown once, so copy it somewhere safe. Send it as a bearer token on every request.

Shell
export QUANTUM_KEY=qp_test_…

curl https://api.quantum-production.com/v1/balance \
  -H "Authorization: Bearer $QUANTUM_KEY"

Your sandbox balance starts at $1,000 of play credit.

2. Set up a product

Add a brand on Brands: the ship-from name for your labels and the address proofs go to. Then on Products, pick one of our products and give it your own SKU code. That code is what you send as items[].sku.

List your SKUs
curl https://api.quantum-production.com/v1/products \
  -H "Authorization: Bearer $QUANTUM_KEY"

3. Price an order

Save an order body as order.json (the next step shows one) and ask for an estimate. It returns exactly what placing the order would charge right now: the copies, the handling fee, shipping and tax. Nothing is held or charged.

Estimate
curl https://api.quantum-production.com/v1/orders/estimate \
  -H "Authorization: Bearer $QUANTUM_KEY" \
  -H "Content-Type: application/json" \
  -d @order.json

4. Place an order

Send the print-ready interior PDF and, for books, the cover PDF as HTTPS links, with the address to ship to. The order is charged to your balance and comes back with status received.

Place an order
curl 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"
      }
    ]
  }'

Preparing files covers what the PDFs need, and Shipping the methods and carriers.

Send a new Idempotency-Key with every order. If a request times out, retry it with the same key and body: you get the original order back instead of a second one.

5. Receive webhooks

On Webhooks in the dashboard, add an HTTPS endpoint. Each event is a POST with the order in it: order.received, order.in_production, order.shipped, and order.needs_attention, order.cancelled or order.rejected when something stops it.

Answer with any 2xx within 10 seconds and do the work afterwards; anything else is retried for 24 hours. Delivery is at least once, so skip an event whose id you've already handled. Check the signature before trusting the body:

Node.js
import { createHmac, timingSafeEqual } from "node:crypto";

// header: the Quantum-Signature header, e.g. "t=1790000000,v1=5f2c…"
// rawBody: the request body exactly as received, before any JSON parsing
export function verifyQuantumSignature(rawBody, header, secret) {
  const pairs = header.split(",").map((part) => part.trim().split("="));
  const t = Number(pairs.find(([k]) => k === "t")?.[1]);
  if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
  // During a secret rotation the header carries two v1 values; either may match.
  return pairs
    .filter(([k]) => k === "v1")
    .some(([, v]) => {
      const given = Buffer.from(v, "hex");
      return given.length === expected.length && timingSafeEqual(given, expected);
    });
}

Order statuses and webhooks has the Python version, the retry schedule and what each status means.

6. Move it along

Sandbox orders move on their own every few minutes. To step through the statuses yourself, advance the order. A shipped sandbox order carries a made-up carrier and tracking number.

Advance a sandbox order
curl -X POST https://api.quantum-production.com/v1/sandbox/orders/$ORDER_ID/advance \
  -H "Authorization: Bearer $QUANTUM_KEY"

Going live

Live orders use a qp_live_ key, which you can create once a card is on file. A new SKU takes real orders straight away. To check a product in your hands first, order one copy with "proof": true; it ships to the brand's address, your default brand's unless you send brand.

Live ordering opens soon. Until then, live keys get 403 forbidden on estimates and orders.

Quickstart · Quantum Production