Order by API
Order custom printed T-shirts, hoodies, hats and bags from Customnia without the website: from your own code or from an AI agent that does it for you. Same prices and print shop as customnia.com, printed in New York or Los Angeles, shipped in the US.
- Base URL
https://api.customnia.com/v1- Format
- JSON in and out; money in US cents (
2280= $22.80).
Selling to your own customers? See the API for stores instead.
How it works
- Sign up with an email: you get a live key and a test key.
- Once: confirm a US mobile number by SMS and save a card on a Stripe page.
- Make a design from a PNG, get a quote, place the order with the total you agreed to. The card is charged, the order goes to print.
The test key (cn_test_…) does everything the live key does, priced the same, but nothing is printed or charged, and it needs no phone or card. Build with it first.
Sign up
POST/signup emails a 6-digit code; POST/signup/verify trades it for the keys, shown once.
curl https://api.customnia.com/v1/signup -H "Content-Type: application/json" -d '{"email": "ann@example.com"}'
curl https://api.customnia.com/v1/signup/verify -H "Content-Type: application/json" \
-d '{"email": "ann@example.com", "code": "123456", "name": "Ann Lee"}'
# → {"api_key": "cn_live_…", "test_key": "cn_test_…", …}
Lost a key? Sign up again with the same email: you get new keys and the old ones stop working. Keep keys secret; anyone with the live key can order on your card.
Confirm a phone
Live orders need a US mobile number confirmed by SMS, once. Virtual, landline and toll-free numbers are not accepted; one number belongs to one account.
curl https://api.customnia.com/v1/account/phone -H "Authorization: Bearer cn_live_…" \
-H "Content-Type: application/json" -d '{"phone": "+1 212 555 0123"}'
curl https://api.customnia.com/v1/account/phone/verify -H "Authorization: Bearer cn_live_…" \
-H "Content-Type: application/json" -d '{"code": "654321"}'
Save a card
POST/account/card answers a url: a Stripe page where you save a card, in a browser, once. The card number goes to Stripe and never to Customnia. GET/account shows the card (brand and last four digits) once it is saved; from then on orders are charged to it without a browser.
Make a design
Pick a blank in GET/catalog (filters: category, brand, color, size, label): it lists colors with prices per size, sizes, and moq, the fewest pieces of a blank in a color an order can have. Then upload a PNG, at least 600 × 600 px; a transparent background prints best.
curl https://api.customnia.com/v1/designs -H "Authorization: Bearer cn_live_…" -F blank_id=4 -F file=@art.png
No picture? Send words: text (lines split by a line break), font from GET/fonts (the designer's 127 families: Anton, Bebas Neue, Pacifico…), text_color as hex, bold, italic, text_side. A photo or a picture on a background? Add remove_background: true and the background comes off first (about 10 seconds).
curl https://api.customnia.com/v1/designs -H "Authorization: Bearer cn_live_…" -H "Content-Type: application/json" \
-d '{"blank_id": 4, "text": "BROOKLYN\nMARATHON 2026", "font": "Bebas Neue", "text_color": "#FFFFFF"}'
See it on the garment: GET/designs/{id}/mockups/{color_id}.jpg. Designs from fabric.js layers, copies to other blanks and the online designer work as in the store guide.
Quote
curl https://api.customnia.com/v1/quotes -H "Authorization: Bearer cn_live_…" -H "Content-Type: application/json" \
-d '{"items": [{"design_id": 101, "color_id": 1, "size_id": 3, "quantity": 12}],
"speed": "REGULAR", "shipping_method": "UPS GROUND", "shipping_address": {"state": "NY"}}'
The options customnia.com offers at payment work here too: review_design (a Customnia designer checks the artwork before printing, price in options.design_check.price), print_as_is (print exactly as sent), tip (cents, for the print team) and promo_code.
Each line comes back with unit_price, discount, tax and total; then totals (items, discount, tax, shipping, total), the location that prints it and ready_by, when it is printed. Nothing is charged.
Order
POST/orders with the items, the address, your own reference for the order and expected_total: the quote total you agreed to.
curl https://api.customnia.com/v1/orders -H "Authorization: Bearer cn_live_…" -H "Content-Type: application/json" \
-d '{"reference": "ann-001", "expected_total": 26380,
"items": [{"design_id": 101, "color_id": 1, "size_id": 3, "quantity": 12}],
"shipping_address": {"first_name": "Ann", "last_name": "Lee", "address1": "1 Main St",
"city": "Brooklyn", "state": "NY", "zip": "11201"}}'
- If the price is no longer
expected_total, the answer is 409price_changedwith the new quote, and nothing is charged. - The same
referenceagain returns the same order and never charges twice: retry after a timeout without fear. - When the bank wants you to confirm, the answer is 402
authentication_requiredwithaction_url: open it, confirm, then send the same order again.
You get an email for every order placed with your key.
Status and cancel
Statuses: received → printing → ready → shipped (with tracking) → delivered, or cancelled. Read them with GET/orders/{id} or GET/orders?updated_since=…, or get them pushed: PATCH/account with {"webhook_url": "https://…"} (a public https address) answers a webhook_secret, shown once; every change of an order then comes as an order.updated webhook signed with it, as for stores. {"new_webhook_secret": true} replaces the secret, {"webhook_url": null} stops the webhooks.
Until printing starts, POST/orders/{id}/cancel cancels and refunds the card in full, and PATCH/orders/{id}/address changes the address.
Prices and speeds
Prices are customnia.com's: the blank in its color and size, the front print, the back print when the design has one, and the printing speed. More pieces of the same blank cost less per piece (the quote shows the discount). Tax and shipping are added as on the website.
speed | Printing | Per piece |
|---|---|---|
REGULAR | 4 Business Days Printing Speed | included |
TWO_BUSINESS_DAYS | 2 Business Days Printing Speed (Cut-off time: 1PM) | +$5.00 |
SAME_DAY | Same Day Printing Speed (Cut-off time: 1pm or Call) | +$10.00 |
Faster speeds exist only where the blank and color allow them; the quote says when one does not. Western states print in Los Angeles, the rest in New York. Ways to ship are in the catalog's shipping.methods; UPS GROUND is the default.
Payments and safety
- Cards are kept by Stripe. Customnia never sees the number.
- An order is charged exactly its quote total, and only with
expected_totalmatching it. - Set your own limits for an agent: PATCH
/accountwith{"limits": {"order": 20000, "daily": 50000}}(cents). Customnia sets none. - Attempts are limited: 10 orders a minute, 3 SMS codes an hour, 3 card pages a day.
Answers
| Answer | Means |
|---|---|
| 201 | Placed and paid (or, with the test key, placed as a test order) |
409 price_changed | The total is not expected_total; nothing charged |
402 card_required | Save a card first |
402 card_declined | The bank declined; save another card |
402 authentication_required | Confirm on action_url, then send the order again |
403 phone_required | Confirm a phone first |
403 order_limit, daily_limit | Over a limit you set |
| 422 | errors names each bad field, for example a quantity under moq |
| 429 | Too many attempts; wait a minute |
AI agents (MCP)
ChatGPT, claude.ai, Claude Desktop and other apps with connectors: add a custom connector with https://api.customnia.com/connect. The app opens Customnia's sign-in (your email, the code from it, test or real orders); no key to copy.
An agent can do all of it through the MCP server at https://api.customnia.com/mcp. No key yet? Connect without one: the agent signs you up with start_signup and verify_signup (you read it the code from the email) and gets your keys.
claude mcp add --transport http customnia https://api.customnia.com/mcp
Then connect again with your key, the test key first:
claude mcp add --transport http customnia https://api.customnia.com/mcp \ --header "Authorization: Bearer cn_test_…"
Tools: get_account, setup_payments (a Customnia page where you confirm your phone and save a card, once), search_catalog, create_design (from a PNG link), get_mockup, quote_order, place_order, get_order, list_orders, cancel_order, change_order_address. The agent asks you for the email code and gives you the setup page for your phone and card, and must show you the total before it orders. Step-by-step instructions written for agents: order.md.
Start with the test key. Give the agent the live key when you are ready to order for real, and set a limit if you like.
Questions: hello@customnia.com