{
    "openapi": "3.1.0",
    "info": {
        "title": "1211 merch API",
        "version": "1.0.0",
        "summary": "Put a picture on a shirt, hoodie, cap, tumbler or tote and get the link where the person buys it.",
        "description": "Send a picture (a public link or an upload) and an item; get back a page where the person sees it on the item, picks sizes and pays. No key and no account. We print each order one at a time, ship it free to US addresses, take the payment and handle sales tax and support.\n\nQuickstart: https://1211holding.com/developers\nFor AI assistants: https://1211holding.com/for-ai",
        "contact": {
            "name": "1211",
            "url": "https://1211holding.com/developers"
        },
        "termsOfService": "https://1211holding.com/legal/tos"
    },
    "servers": [
        {
            "url": "https://1211holding.com"
        }
    ],
    "externalDocs": {
        "description": "Quickstart in curl, Python and JavaScript",
        "url": "https://1211holding.com/developers"
    },
    "paths": {
        "/v1/catalog": {
            "get": {
                "operationId": "list_items",
                "summary": "Everything we print on, with colours, sizes, print sizes and prices",
                "description": "Every item with its colours, sizes, how big a picture prints on each side, the pixels a picture needs (150 per inch prints well, 300 is sharp), what the person pays (US shipping included) and what craft producers charge for the same kind of item. Limit: 300 reads per address per hour.",
                "responses": {
                    "200": {
                        "description": "The catalog.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Catalog"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many reads from this address.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    }
                },
                "x-mcp-tool": true
            }
        },
        "/v1/art": {
            "post": {
                "operationId": "check_art",
                "summary": "Upload a picture (or give its link) and learn how big it prints",
                "description": "Send the picture as a multipart field art_file, or JSON {\"url\": \"https://...\"}. PNG, JPG, WEBP, GIF, HEIC or PDF, up to 25 MB. Returns an upload id to use in a design as {\"art\": {\"upload\": \"<id>\"}}, its size, and how big it prints well. Limit: 20 per address per hour.",
                "responses": {
                    "201": {
                        "description": "Uploaded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ArtUpload"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "The picture could not be used; problems say why and how to fix it.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many uploads from this address.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "url"
                                ],
                                "properties": {
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "description": "A public http(s) link to the picture."
                                    }
                                }
                            }
                        },
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "art_file"
                                ],
                                "properties": {
                                    "art_file": {
                                        "type": "string",
                                        "contentMediaType": "application/octet-stream",
                                        "description": "The picture file."
                                    }
                                }
                            }
                        }
                    }
                },
                "x-mcp-tool": true
            }
        },
        "/v1/designs": {
            "post": {
                "operationId": "create_design",
                "summary": "Put a picture on an item and get the link where the person buys it",
                "description": "Makes a design from a picture (a public link or an upload id) on an item and colour, and returns the page where the person sees it, picks sizes and pays (url), a picture of the result, how big each side prints, the price and any problems. No key and no account; the person pays on our page, so never check out for them. A problem never blocks what is still possible: art too small for a back print still makes the design on the front, and says so. Only art the person made or may print. Limit: 30 designs per address per hour.",
                "responses": {
                    "201": {
                        "description": "The design.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Design"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "The body is not JSON.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Nothing could be printed; problems say why and how to fix it.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many designs from this address.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "New designs are paused for today.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/DesignRequest"
                            }
                        }
                    }
                },
                "x-mcp-tool": true
            }
        },
        "/v1/designs/{design}": {
            "get": {
                "operationId": "get_design",
                "summary": "Read a design again",
                "description": "The same object create_design returned: its link, pictures, print sizes and price.",
                "responses": {
                    "200": {
                        "description": "The design.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Design"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such design (or it expired).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "design",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9A-Za-z]{22}$"
                        }
                    }
                ],
                "x-mcp-tool": true
            }
        },
        "/v1/feedback": {
            "post": {
                "operationId": "report_problem",
                "summary": "Tell 1211 something is wrong",
                "description": "Report a problem met while using this API: a picture refused that should have printed (art_wrongly_refused), a wrong price, a picture of the result that does not match (wrong_mockup), a link that does not open (broken_link), a checkout that failed (checkout_failed), an item people want that we do not make (missing_item), or other. Include the design id when it is about one design. Never include the person's name, email or other personal details. A person reads every report. Limit: 20 per address per hour.",
                "responses": {
                    "201": {
                        "description": "Received.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "id": {
                                            "type": "integer"
                                        },
                                        "says": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Not a kind of problem we file.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many reports from this address.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "kind"
                                ],
                                "properties": {
                                    "kind": {
                                        "type": "string",
                                        "enum": [
                                            "art_wrongly_refused",
                                            "wrong_price",
                                            "wrong_mockup",
                                            "broken_link",
                                            "checkout_failed",
                                            "missing_item",
                                            "other"
                                        ]
                                    },
                                    "design": {
                                        "type": "string",
                                        "pattern": "^[0-9A-Za-z]{22}$"
                                    },
                                    "detail": {
                                        "type": "string",
                                        "maxLength": 1000,
                                        "description": "What was wrong, in a sentence or two."
                                    }
                                }
                            }
                        }
                    }
                },
                "x-mcp-tool": true
            }
        },
        "/v1/art/{upload}.png": {
            "get": {
                "operationId": "get_art_preview",
                "summary": "A small preview of an upload",
                "description": "A PNG up to 640 pixels across. The upload id is the key.",
                "responses": {
                    "200": {
                        "description": "The preview.",
                        "content": {
                            "image/png": {
                                "schema": {
                                    "type": "string",
                                    "contentMediaType": "image/png"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such upload."
                    }
                },
                "parameters": [
                    {
                        "name": "upload",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[0-9A-Za-z]{22}$"
                        }
                    }
                ],
                "x-mcp-tool": false
            }
        },
        "/v1/place": {
            "get": {
                "operationId": "get_placement",
                "summary": "Where a picture of w x h pixels sits on the product photo",
                "description": "For drawing your own preview: the box the print occupies on the item's product photo, in percent of the photo. The same numbers the order is placed with.",
                "responses": {
                    "200": {
                        "description": "The box.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PlaceBox"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown item, or it has no such side.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Failure"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "item",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "side",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "front",
                                "back",
                                "center"
                            ],
                            "default": "front"
                        },
                        "description": "center = the big centered front."
                    },
                    {
                        "name": "w",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 0
                        }
                    },
                    {
                        "name": "h",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 0
                        }
                    }
                ],
                "x-mcp-tool": false
            }
        }
    },
    "components": {
        "schemas": {
            "Problem": {
                "type": "object",
                "required": [
                    "code",
                    "where",
                    "says",
                    "fix"
                ],
                "properties": {
                    "code": {
                        "type": "string",
                        "enum": [
                            "item_unknown",
                            "color_unknown",
                            "no_back",
                            "art_missing",
                            "art_unreachable",
                            "art_not_image",
                            "art_too_big",
                            "art_too_small",
                            "art_small_for_side",
                            "no_center",
                            "rate_limited",
                            "busy",
                            "bad_json",
                            "design_unknown",
                            "not_found",
                            "kind_unknown",
                            "dev_unknown",
                            "markup_too_high"
                        ],
                        "description": "What went wrong, as a stable code."
                    },
                    "where": {
                        "type": "string",
                        "description": "The field it is about, such as \"item\" or \"front.art\"; empty when general."
                    },
                    "says": {
                        "type": "string",
                        "description": "One sentence a person can read."
                    },
                    "fix": {
                        "type": "string",
                        "description": "What to send instead; empty when there is nothing to change."
                    },
                    "retry_after": {
                        "type": "integer",
                        "description": "Seconds to wait before trying again (rate_limited only)."
                    }
                }
            },
            "Failure": {
                "type": "object",
                "required": [
                    "ok",
                    "problems"
                ],
                "properties": {
                    "ok": {
                        "const": false
                    },
                    "problems": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Problem"
                        }
                    }
                }
            },
            "ArtRef": {
                "description": "The picture for one side: a public link we fetch once, or an upload id from POST /v1/art.",
                "oneOf": [
                    {
                        "type": "object",
                        "required": [
                            "url"
                        ],
                        "additionalProperties": false,
                        "properties": {
                            "url": {
                                "type": "string",
                                "format": "uri",
                                "description": "A public http(s) link to a PNG, JPG, WEBP, GIF, HEIC or PDF."
                            }
                        }
                    },
                    {
                        "type": "object",
                        "required": [
                            "upload"
                        ],
                        "additionalProperties": false,
                        "properties": {
                            "upload": {
                                "type": "string",
                                "pattern": "^[0-9A-Za-z]{22}$",
                                "description": "An upload id from POST /v1/art."
                            }
                        }
                    },
                    {
                        "type": "object",
                        "required": [
                            "svg"
                        ],
                        "additionalProperties": false,
                        "properties": {
                            "svg": {
                                "type": "string",
                                "maxLength": 400000,
                                "description": "SVG markup you wrote: shapes and text, no scripts or linked files. Give it a viewBox. We draw it 3,600 px on its longest side. Fonts: Lato, DejaVu Sans, DejaVu Serif, Liberation Sans, Liberation Serif, Nimbus Sans, URW Gothic, URW Bookman, C059, P052, Z003, Noto Color Emoji."
                            }
                        }
                    },
                    {
                        "type": "object",
                        "required": [
                            "file"
                        ],
                        "additionalProperties": false,
                        "properties": {
                            "file": {
                                "type": "object",
                                "description": "A file as ChatGPT passes it.",
                                "properties": {
                                    "download_url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "file_id": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                ]
            },
            "Side": {
                "type": "object",
                "required": [
                    "art"
                ],
                "properties": {
                    "art": {
                        "$ref": "#/components/schemas/ArtRef"
                    },
                    "placement": {
                        "type": "string",
                        "enum": [
                            "chest",
                            "center"
                        ],
                        "default": "chest",
                        "description": "Front only: chest (small, on the left chest) or center (big and centered, up to 12 in; T-shirts, sweatshirts and hoodies). A picture too small for a big front goes on the left chest, and problems say so."
                    }
                }
            },
            "DesignRequest": {
                "type": "object",
                "required": [
                    "item"
                ],
                "description": "At least one of front or back. A shirt's front prints small on the left chest, or big and centered with \"placement\": \"center\"; its back prints large. Items without a back print take the front only.",
                "properties": {
                    "item": {
                        "type": "string",
                        "enum": [
                            "tee",
                            "hoodie",
                            "crewneck",
                            "tee-classic",
                            "polo",
                            "quarter-zip",
                            "cap",
                            "trucker",
                            "tumbler",
                            "tote"
                        ],
                        "description": "The item, from GET /v1/catalog."
                    },
                    "color": {
                        "type": "string",
                        "description": "One of the item's colours from GET /v1/catalog; case and spaces do not matter. Left out, the item's default colour; an unknown colour is replaced by the default and reported as color_unknown."
                    },
                    "front": {
                        "$ref": "#/components/schemas/Side"
                    },
                    "back": {
                        "$ref": "#/components/schemas/Side"
                    },
                    "title": {
                        "type": "string",
                        "maxLength": 80,
                        "description": "A name for the design, shown on its page."
                    },
                    "dev": {
                        "type": "string",
                        "pattern": "^dev_[a-z0-9]{12}$",
                        "description": "Developers: your developer id from https://1211holding.com/developers/earn, with markup_usd."
                    },
                    "markup_usd": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 50,
                        "description": "Developers: dollars added to each item; the buyer pays our price plus this and you keep it less processing fees."
                    },
                    "size": {
                        "type": "string",
                        "description": "Optional: a size to start with on the page (S, M, L, XL, 2XL ...; \"large\" and \"xxl\" work too). The returned url carries it; the person can change it."
                    },
                    "ref": {
                        "type": "string",
                        "maxLength": 80,
                        "description": "Your app's or assistant's name (letters, digits, . _ -), so we can see who sends people."
                    }
                }
            },
            "DesignSide": {
                "type": "object",
                "properties": {
                    "ok": {
                        "type": "boolean",
                        "description": "True when the picture has enough pixels to print well at this size."
                    },
                    "prints_in": {
                        "type": "array",
                        "items": {
                            "type": "number"
                        },
                        "minItems": 2,
                        "maxItems": 2,
                        "description": "Printed width and height in inches."
                    },
                    "dpi": {
                        "type": "number",
                        "description": "Pixels per printed inch (150 prints well, 300 is sharp)."
                    },
                    "px": {
                        "type": "array",
                        "items": {
                            "type": "number"
                        },
                        "minItems": 2,
                        "maxItems": 2,
                        "description": "The picture's width and height in pixels."
                    },
                    "says": {
                        "type": "string",
                        "description": "How it will print, in one sentence."
                    },
                    "placement": {
                        "type": "string",
                        "enum": [
                            "chest",
                            "center"
                        ],
                        "description": "Front only: where the front prints."
                    }
                }
            },
            "Design": {
                "type": "object",
                "required": [
                    "design",
                    "url",
                    "item",
                    "color",
                    "price",
                    "problems"
                ],
                "properties": {
                    "design": {
                        "type": "string",
                        "pattern": "^[0-9A-Za-z]{22}$",
                        "description": "The design id."
                    },
                    "url": {
                        "type": "string",
                        "format": "uri",
                        "description": "The page where the person sees it, picks sizes and pays. Give them this link."
                    },
                    "mockup": {
                        "type": "object",
                        "description": "A picture of the result per side (null where the side is not printed).",
                        "properties": {
                            "front": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "uri"
                            },
                            "back": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "uri"
                            }
                        }
                    },
                    "item": {
                        "type": "string"
                    },
                    "item_name": {
                        "type": "string"
                    },
                    "color": {
                        "type": "string"
                    },
                    "title": {
                        "type": "string"
                    },
                    "sides": {
                        "type": "object",
                        "properties": {
                            "front": {
                                "$ref": "#/components/schemas/DesignSide"
                            },
                            "back": {
                                "$ref": "#/components/schemas/DesignSide"
                            }
                        }
                    },
                    "price": {
                        "type": "object",
                        "properties": {
                            "usd": {
                                "type": "number",
                                "description": "What the person pays for one, US shipping included."
                            },
                            "bigger_sizes_usd": {
                                "type": "object",
                                "additionalProperties": {
                                    "type": "number"
                                },
                                "description": "Sizes that cost more, by size."
                            },
                            "shipping": {
                                "type": "string"
                            }
                        }
                    },
                    "problems": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "description": "What did not go as asked but did not stop the design (for example, art too small for a back print was put on the front)."
                    },
                    "expires": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "A design that is never ordered is removed after this date."
                    }
                }
            },
            "ArtUpload": {
                "type": "object",
                "required": [
                    "ok",
                    "upload",
                    "w",
                    "h"
                ],
                "properties": {
                    "ok": {
                        "const": true
                    },
                    "upload": {
                        "type": "string",
                        "pattern": "^[0-9A-Za-z]{22}$",
                        "description": "Use as {\"art\": {\"upload\": \"<id>\"}}."
                    },
                    "w": {
                        "type": "integer"
                    },
                    "h": {
                        "type": "integer"
                    },
                    "grade": {
                        "type": "string",
                        "description": "How well it prints, as a word."
                    },
                    "says": {
                        "type": "string",
                        "description": "How big it prints well, in one sentence."
                    },
                    "preview": {
                        "type": "string",
                        "format": "uri",
                        "description": "A small PNG of the upload."
                    },
                    "expires_days": {
                        "type": "integer"
                    }
                }
            },
            "PrintArea": {
                "type": "object",
                "properties": {
                    "where": {
                        "type": "string"
                    },
                    "max_w_in": {
                        "type": "number"
                    },
                    "max_h_in": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "px_good": {
                        "type": "integer",
                        "description": "Pixels across that fill the area at 150 per inch."
                    },
                    "px_sharp": {
                        "type": "integer",
                        "description": "Pixels across that fill it at 300 per inch."
                    },
                    "min_in": {
                        "type": "number"
                    }
                }
            },
            "CatalogItem": {
                "type": "object",
                "properties": {
                    "item": {
                        "type": "string",
                        "description": "Use this as \"item\"."
                    },
                    "slug": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "garment": {
                        "type": "string"
                    },
                    "page": {
                        "type": "string",
                        "format": "uri"
                    },
                    "colors": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string"
                                },
                                "hex": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "default_color": {
                        "type": "string"
                    },
                    "sizes": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "sides": {
                        "type": "object",
                        "properties": {
                            "front": {
                                "$ref": "#/components/schemas/PrintArea"
                            },
                            "back": {
                                "$ref": "#/components/schemas/PrintArea"
                            }
                        }
                    },
                    "price_usd": {
                        "type": "object",
                        "description": "What the person pays, US shipping included.",
                        "properties": {
                            "one_side": {
                                "type": "number"
                            },
                            "both_sides": {
                                "type": "number"
                            },
                            "bigger_sizes": {
                                "type": "object",
                                "additionalProperties": {
                                    "type": "number"
                                }
                            },
                            "bigger_sizes_both_sides": {
                                "type": "object",
                                "additionalProperties": {
                                    "type": "number"
                                }
                            }
                        }
                    },
                    "market_usd": {
                        "type": "object",
                        "description": "What craft producers charge for the same kind of item.",
                        "properties": {
                            "low": {
                                "type": "number"
                            },
                            "middle": {
                                "type": "number"
                            },
                            "high": {
                                "type": "number"
                            }
                        }
                    },
                    "make_link": {
                        "type": "string"
                    }
                }
            },
            "Catalog": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "version": {
                        "type": "string"
                    },
                    "currency": {
                        "type": "string"
                    },
                    "shipping": {
                        "type": "string"
                    },
                    "prices_checked": {
                        "type": "string"
                    },
                    "market_checked": {
                        "type": "string"
                    },
                    "market_stale": {
                        "type": "boolean"
                    },
                    "art": {
                        "type": "object",
                        "properties": {
                            "formats": {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            },
                            "max_mb": {
                                "type": "integer"
                            },
                            "good_dpi": {
                                "type": "integer"
                            },
                            "sharp_dpi": {
                                "type": "integer"
                            },
                            "min_px": {
                                "type": "integer"
                            },
                            "placement": {
                                "type": "string"
                            }
                        }
                    },
                    "make_link": {
                        "type": "string",
                        "description": "The link template a person can open directly."
                    },
                    "docs": {
                        "type": "string",
                        "format": "uri"
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/CatalogItem"
                        }
                    }
                }
            },
            "PlaceBox": {
                "type": "object",
                "properties": {
                    "item": {
                        "type": "string"
                    },
                    "side": {
                        "type": "string"
                    },
                    "box": {
                        "type": "object",
                        "description": "Percent of the product photo.",
                        "properties": {
                            "left": {
                                "type": "number"
                            },
                            "top": {
                                "type": "number"
                            },
                            "width": {
                                "type": "number"
                            },
                            "height": {
                                "type": "number"
                            }
                        }
                    }
                }
            }
        }
    }
}