Front and back on one item
A shirt printed on the front and the back is one item: one order at the
printshop, one parcel, one charge. Each side is a design of its own,
committed for its own placement on the same blank, and printed on its own.
POST /v1/orders then orders the prints together, as one item.
1. Commit a design for each placement
Commit one design per side, each naming the blank and its own placement:
{
"templateId": "tshirt-back@1",
"values": { "name": { "content": "Alexandra" } },
"blankId": "blank_tshirt",
"placementId": "back"
}
Approve each design and print it, as for any design (Design to order). You now hold a completed print of each side.
On the hosted designer, one link for both sides
A store that sends its customer to the hosted designer hands out one link for
the whole item: each side its own template, blank and placement, and the
size menu, photos and preselection it sells that side with. The page shows a
step per side, offers approving once the customer has opened every side, and
sends them back with a proof of each, under the side’s key:
{
"sides": [
{
"key": "front",
"label": "Front",
"templateId": "tshirt-front",
"blankId": "blank_tshirt",
"placementId": "front",
"printSizes": [
{ "widthMm": 280, "heightMm": 360, "label": "Large" },
{ "widthMm": 200, "heightMm": 257, "label": "Medium" }
],
"selectedPrintSizeIndex": 1
},
{
"key": "back",
"label": "Back",
"templateId": "tshirt-back",
"blankId": "blank_tshirt",
"placementId": "back"
}
],
"returnUrl": "https://shop.example/cart",
"state": "cart-10482",
"locale": "sv"
}
The customer comes back to
https://shop.example/cart?state=cart-10482&proofToken[front]=…&proofToken[back]=…
(the brackets percent-encoded, which PHP reads as the array
$_GET['proofToken']), only once every side’s proof is made. Commit each
side’s proof with POST /v1/designs and its proofToken, then continue as
above. A link with sides must name a returnUrl, holds two to ten sides,
and names a side’s options only in its entry. A side without templateId is
the path’s template.
A designer is built for up to four sides: a garment’s front, back and two sleeves. A link with more is still made, and its response carries a warning for you, never shown to the customer:
{
"id": "shl_9a8b7c6d5e4f3a2b1c0d9e8f",
"token": "EXAMPLE_designer_link_token_not_a_real_one",
"url": "https://app.pixonaut.example/h/design/EXAMPLE_designer_link_token_not_a_real_one?lang=sv",
"expiresAt": 1791972000000,
"name": null,
"brandId": null,
"designLimit": null,
"printAreaFrame": false,
"placementFrame": false,
"locale": "sv",
"warnings": [{ "code": "sides_over_recommended", "recommended": 4, "sides": 5 }]
}
Each side is one more step on the hosted page, one more designer, canvas and
photo set in the customer’s browser, and one more proofToken[<key>] on the
return address. The SDK warns the same way, in the console, when it is mounted
with more than four placements.
2. Order the prints as one item
Send every print of the item, the one you think of as first first. The first
is the order’s lead: the order’s printId names it.
{
"prints": [
{ "printId": "c4d5e6f7-a8b9-4c0d-9e1f-2a3b4c5d6e7f" },
{ "printId": "d5e6f7a8-b9c0-4d1e-8f2a-3b4c5d6e7f80" }
],
"quantity": 1,
"externalRef": "WEB-10482-1",
"recipient": { "name": "Alexandra Lind", "email": "[email protected]" },
"shippingAddress": {
"company": "Lind Design AB",
"line1": "12 High Street",
"postalCode": "SW1A 1AA",
"city": "London",
"country": "GB"
}
}
The order answers with every print, the lead first, and each print’s placement:
{
"id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
"tenantId": "acme",
"printId": "c4d5e6f7-a8b9-4c0d-9e1f-2a3b4c5d6e7f",
"designId": "6f1c8a2b-3d4e-4f5a-8b6c-7d8e9f0a1b2c",
"printIds": [
"c4d5e6f7-a8b9-4c0d-9e1f-2a3b4c5d6e7f",
"d5e6f7a8-b9c0-4d1e-8f2a-3b4c5d6e7f80"
],
"prints": [
{
"printId": "c4d5e6f7-a8b9-4c0d-9e1f-2a3b4c5d6e7f",
"designId": "6f1c8a2b-3d4e-4f5a-8b6c-7d8e9f0a1b2c",
"designRevision": 1,
"placementId": "front",
"printedAs": "Front",
"spotOutput": "process",
"status": "completed",
"placementFields": []
},
{
"printId": "d5e6f7a8-b9c0-4d1e-8f2a-3b4c5d6e7f80",
"designId": "7a2d9b3c-4e5f-4a6b-9c7d-8e9f0a1b2c3d",
"designRevision": 1,
"placementId": "back",
"printedAs": "Back",
"spotOutput": "process",
"status": "completed",
"placementFields": []
}
],
"adapter": "printful",
"quantity": 1,
"externalRef": "WEB-10482-1",
"recipient": {
"name": "Alexandra Lind",
"email": "[email protected]"
},
"shippingAddress": {
"company": "Lind Design AB",
"line1": "12 High Street",
"postalCode": "SW1A 1AA",
"city": "London",
"country": "GB"
},
"shipTo": null,
"printshopConnectionId": "0b1c2d3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
"printshopName": "Printful",
"spotOutput": "process",
"externalOrderRef": "PF-889123",
"status": "queued",
"lastError": null,
"failureKind": null,
"hold": null,
"tracking": null,
"submittedAt": 1791886447000,
"lastCheckedAt": null,
"updatedAt": 1791886448000,
"replacesOrderId": null,
"replacedByOrderId": null,
"personalDataErasedAt": null,
"blankId": "blank_classic_tee",
"variantRef": "v_3f9a1c2b7d4e8a01",
"variant": {
"ref": "v_3f9a1c2b7d4e8a01",
"options": {
"Color": "White",
"Size": "M"
},
"fields": [
{
"name": "catalogVariantId",
"value": "4012",
"source": "own"
}
]
},
"printshopAsPlaced": {
"name": "Printful",
"adapter": "printful"
},
"delivery": null,
"blank": {
"name": "Classic tee",
"optionAxes": [
"Color",
"Size"
],
"variants": 12
}
}
Nothing is ordered, and the order is not written, when the prints are not one
item: a print committed before its placement was recorded
(print_without_placement), prints on different blanks, or some on a blank
and some on none (mixed_blanks), or two in one placement
(duplicate_placement). The same holds when the printshop cannot make them as
one item (printshop_cannot_combine), or when the designs disagree on what it
makes one item from, such as Printful’s variant (prints_disagree, naming the
key). Each is a 422.
An item with no blank
A sign or a coaster printed on both faces has no blank: commit each face’s
design with no blankId or placementId, and order the prints together as
above. Prints that are all on no blank are one item, with no placement to
compare. The order goes to the printshop the first print’s design was
committed with, else the request’s printshopId, else the workspace default;
with none it is refused 409 print_needs_printshop. A print whose design was
committed with another printshop is refused 422 print_committed_elsewhere,
naming it.
order.submitted and every later order.* event carry printIds. Find the
order by any of its prints with GET /v1/orders?printId=.
3. Hand each print’s file to the printshop
A partner printshop receives every print as a file of the one item. A
printshop you describe yourself sends every print too, once its steps are
written to (its setup page in the docs says how). When you fetch the files
yourself, name the print:
GET /v1/orders/{id}/job/files?printId= and GET /v1/orders/{id}/job/file?printId=.
Without printId an order of several prints answers 422 print_id_required,
naming its printIds.
Cancelling before it is made
If the customer cancels before the item is made, POST /v1/orders/{id}/cancel
asks the printshop to stop the whole item, and the order becomes cancelled
once it has. A printshop that has begun it answers 409 order_at_printshop.
Refunding the customer stays yours.
Questions? Write to [email protected].