A print-on-demand API with no account and no key
Send a picture; get back a link where your user sees it on a shirt, hoodie, cap, tumbler or tote and buys it. We print each order, ship it free to US addresses, take the payment and handle sales tax and support. One request, nothing to sign up for.
- No key, no account, no store to set up. Most print-on-demand APIs need all three before the first call.
- You never touch payments, printing, shipping or tax. Your user pays on our page; there is no charge to you.
- Works from a browser. Every response allows any origin, so a web app can call it directly.
Quickstart
curl -s https://1211holding.com/v1/designs \
-H 'Content-Type: application/json' \
-d '{"item": "hoodie", "color": "Black",
"front": {"art": {"url": "https://example.com/your-image.png"}},
"ref": "your-app"}'
The answer (status 201). Give your user url:
{
"design": "3fQx9VbP2k7mLr1sT8wZ4a",
"url": "https://1211holding.com/d/3fQx9VbP2k7mLr1sT8wZ4a",
"mockup": {
"front": "https://1211holding.com/d/3fQx9VbP2k7mLr1sT8wZ4a/front.png",
"back": null
},
"item": "hoodie",
"item_name": "Hoodie",
"color": "Black",
"title": "",
"sides": {
"front": {
"ok": true,
"prints_in": [
3.5,
3.5
],
"dpi": 343,
"px": [
1200,
1200
],
"says": "Prints sharp at this size."
}
},
"price": {
"usd": 40,
"bigger_sizes_usd": {
"2XL": 42,
"3XL": 43,
"4XL": 44
},
"shipping": "free (US)"
},
"problems": [],
"expires": "2026-11-01"
}
Python
import requests
API = "https://1211holding.com/v1"
# 1. A picture that is already online: one request.
r = requests.post(f"{API}/designs", json={
"item": "hoodie",
"color": "Black",
"front": {"art": {"url": "https://example.com/your-image.png"}},
"ref": "your-app",
})
d = r.json()
if r.status_code == 201:
print(d["url"]) # send your user here: they pick a size and pay
else:
for p in d["problems"]:
print(p["code"], p["says"], p["fix"])
# 2. A file on disk: upload it, then use its id.
with open("drawing.png", "rb") as f:
up = requests.post(f"{API}/art", files={"art_file": f}).json()
d = requests.post(f"{API}/designs", json={"item": "tee", "front": {"art": {"upload": up["upload"]}}}).json()
print(d["url"])
JavaScript
const API = "https://1211holding.com/v1";
// Works from a browser too: the API sends Access-Control-Allow-Origin: *
const res = await fetch(`${API}/designs`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
item: "hoodie",
color: "Black",
front: { art: { url: "https://example.com/your-image.png" } },
ref: "your-app",
}),
});
const d = await res.json();
if (res.status === 201) window.open(d.url); // the page where your user buys it
else console.log(d.problems);
// A file the user picked in <input type="file" id="pic">:
const fd = new FormData();
fd.append("art_file", document.getElementById("pic").files[0]);
const up = await (await fetch(`${API}/art`, { method: "POST", body: fd })).json();
// then use { art: { upload: up.upload } } as above
No code at all
A link opens the same thing, with the picture already on the item. Anyone can write it, including an AI assistant in a chat:
https://1211holding.com/make?item=hoodie&color=Black&art=https://example.com/your-image.png&side=front&ref=your-app
side is front, back or both; add front=center for a big centered front instead of
the small left-chest print (in the API: "front": {"art": {...}, "placement": "center"}), and size=L to start
with a size. The person can change it, add more, and pays on the page.
What comes back
url: the page where the person sees the item, picks sizes and pays. This is the one to hand over.mockup: a picture of the result for each printed side.sides: how big each side prints in inches, its pixels per inch, and one sentence on how it will look.price.usd: what one costs, US shipping included; bigger sizes are listed when they cost more.problems: anything that didn’t go as asked but didn’t stop the design. A picture too small for a back print still makes the design on the front, and says so.expires: a design nobody orders is removed after 30 days.
Items and prices
Read them live from GET /v1/catalog; today they are:
| item | Name | One side | Front and back |
|---|---|---|---|
tee | T-shirt | $22 | $28 |
hoodie | Hoodie | $40 | $45 |
crewneck | Sweatshirt | $40 | $45 |
tee-classic | Classic T-shirt | $22 | $27 |
polo | Polo shirt | $34 | $40 |
quarter-zip | Quarter-zip | $45 | $52 |
cap | Cap | $23 | front only |
trucker | Trucker hat | $25 | front only |
tumbler | 20 oz tumbler | $28 | front only |
tote | Tote bag | $18 | front only |
Prices include shipping to a US address. A shirt’s front prints small on the left chest; its back prints large.
Errors you can fix
Every error is {"ok": false, "problems": [{"code", "where", "says", "fix"}]}, so a program can correct it and try again.
item_unknown: Not an item we make; fix lists them.color_unknown: Not a colour of that item; the default was used and fix lists the colours.no_back: The item prints on the front only.art_missing: No art was given, or an upload expired.art_unreachable: The link did not return an image (the HTTP status is in says). Use a public link or upload the file.art_not_image: The file is not PNG, JPG, WEBP, GIF, HEIC, PDF or SVG (or the SVG has scripts or linked files).art_too_big: The file is over the size limit.art_too_small: Too few pixels for any print.art_small_for_side: Fine for the front, too small for the back or a big front (it went on the left chest); fix says how many pixels that needs.no_center: The item has no big centered front, so the front prints on the left chest; fix lists the items that have one.rate_limited: Too many requests from one address in an hour; retry_after is in seconds.busy: New designs are paused for the rest of the day.bad_json: The body is not JSON.design_unknown: No such design, or it expired.not_found: No such endpoint.kind_unknown: report_problem was given a kind it does not file; fix lists the kinds.
Limits and rules
- Per address per hour: 30 designs, 20 uploads, 300 catalog reads. Calls made from your users’ browsers count against each user’s own address.
- Pictures: PNG, JPG, WEBP, GIF, HEIC or PDF, up to 25 MB. About 150 pixels per printed inch prints well; 300 is sharp.
- Only art your user made or has permission to print; they confirm it when they buy, and our terms make them responsible for it.
- Never check out for anyone: the person pays on our page.
- Shipping is to US addresses only.
Reference
- /openapi.json: the whole API as OpenAPI 3.1.
- /mcp: the same tools as an MCP server (streamable HTTP, no sign-in), for agents.
- /v1/catalog: items, colours, sizes, print sizes and prices.
- /for-ai: the same API written for AI assistants, and /llms.txt.