Skip to content

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.

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

Items and prices

Read them live from GET /v1/catalog; today they are:

itemNameOne sideFront and back
teeT-shirt $22$28
hoodieHoodie $40$45
crewneckSweatshirt $40$45
tee-classicClassic T-shirt $22$27
poloPolo shirt $34$40
quarter-zipQuarter-zip $45$52
capCap $23front only
truckerTrucker hat $25front only
tumbler20 oz tumbler $28front only
toteTote bag $18front 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.

Limits and rules

Reference