All endpoints accept JSON over HTTPS. Put your api_key inside the request body (not a header) and send every request as a POST with Content-Type: application/json. Generate / rotate your key in the seller control panel.
POST.application/json — UTF-8 only.api_key field inside the JSON body.{ "status": "success", ...endpoint-specific... }{ "response": { "failure": { "code": "3", "message": "Invalid Authorization key" } } }Submit one or more orders for fulfillment. Accepts existing `product_id`s or a new-product payload inline. Returns a shiplist ID that groups the orders for batch tracking.
| Field | Type | Description |
|---|---|---|
| api_key required | string | Your API key from /cp/api. |
| shipping.fullname required | string | Recipient's full name. |
| shipping.address1 required | string | Street address (must include house number). |
| shipping.address2 optional | string | Apartment / unit number (optional). |
| shipping.city required | string | City. |
| shipping.state required | string | State/province. 2-letter code for US/CA. |
| shipping.zip required | string | Postal/zip code. |
| shipping.country required | string | 2-letter country code (US, CA, GB, …). |
| shipping.phone optional | string | Recipient's phone — required by some carriers. |
| shipping.email optional | string | Recipient's email — used for shipping notifications if your store relay is enabled. |
| order required | array | Single order object OR an array of order objects for batch submission. |
| order[].product_id optional | integer | Existing product ID (from CreateProduct). Omit if supplying `order[].product.*` inline. |
| order[].product.title optional | string | If creating on the fly: product title. |
| order[].product.url optional | string | If creating on the fly: design image URL (HTTPS PNG). |
| order[].size required | string | Size code (S, M, L, XL, 2XL…). |
| order[].color required | string | Colour name. |
| order[].quantity required | integer | Quantity — at least 1. |
| order[].backprint optional | boolean | `true` if back-print artwork was supplied with the product. Default `false`. |
| order[].priority_shipping optional | boolean | Priority lane (costs more, ships in 1–2 business days). |
| order[].comments optional | string | Free-text note passed through to production. |
| order[].market_id1 optional | string | Your internal order ID — stored for reference and returned on LookupOrder. |
curl -X POST https://www.tshirtgang.com/api/v2/CreateOrder/ \
-H "Content-Type: application/json" \
-d '{"api_key":"YOUR_API_KEY","shipping":{"fullname":"Jane Doe","address1":"123 Main St","city":"Toronto","state":"ON","zip":"M5V 2T6","country":"CA"},"order":[{"product_id":98765,"size":"M","color":"Black","quantity":1}]}'
<?php
$ch = curl_init('https://www.tshirtgang.com/api/v2/CreateOrder/');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{\"api_key\":\"YOUR_API_KEY\",\"shipping\":{\"fullname\":\"Jane Doe\",\"address1\":\"123 Main St\",\"city\":\"Toronto\",\"state\":\"ON\",\"zip\":\"M5V 2T6\",\"country\":\"CA\"},\"order\":[{\"product_id\":98765,\"size\":\"M\",\"color\":\"Black\",\"quantity\":1}]}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
$data = json_decode($res, true);
curl_close($ch);
print_r($data);
// Node 18+ (native fetch)
const res = await fetch('https://www.tshirtgang.com/api/v2/CreateOrder/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"api_key": "YOUR_API_KEY",
"shipping": {
"fullname": "Jane Doe",
"address1": "123 Main St",
"city": "Toronto",
"state": "ON",
"zip": "M5V 2T6",
"country": "CA"
},
"order": [
{
"product_id": 98765,
"size": "M",
"color": "Black",
"quantity": 1
}
]
})
});
const data = await res.json();
console.log(data);
# pip install requests
import requests
res = requests.post(
'https://www.tshirtgang.com/api/v2/CreateOrder/',
json={
"api_key": "YOUR_API_KEY",
"shipping": {
"fullname": "Jane Doe",
"address1": "123 Main St",
"city": "Toronto",
"state": "ON",
"zip": "M5V 2T6",
"country": "CA"
},
"order": [
{
"product_id": 98765,
"size": "M",
"color": "Black",
"quantity": 1
}
]
}
)
print(res.json())
{
"status": "success",
"shiplist": "SL-554321",
"orders": [
{
"order_id": 554321,
"product_id": 98765,
"estimated_ship": "2026-04-19"
}
]
}
| Field | Type | Description |
|---|---|---|
| status | string | `success` on a valid response. |
| shiplist | string | Grouping ID — every order in this batch shares this value; lookup individual orders via LookupOrder. |
| orders | array | Per-order details; indexes match the request `order[]` order. |
| orders[].order_id | integer | Our order ID. |
| orders[].product_id | integer | The product that was (or was created) and ordered. |
| orders[].estimated_ship | string | Estimated ship date (YYYY-MM-DD). |
Fetch a single order by either Tshirtgang `order_id` or your own `market_id1`. Returns full details (address, item, status, tracking, receipts).
| Field | Type | Description |
|---|---|---|
| api_key required | string | Your API key from /cp/api. |
| order_id optional | integer | Our numeric order ID. Exactly one of `order_id` / `market_id1` must be supplied. |
| market_id1 optional | string | Your internal order ID. |
curl -X POST https://www.tshirtgang.com/api/v2/LookupOrder/ \
-H "Content-Type: application/json" \
-d '{"api_key":"YOUR_API_KEY","market_id1":"YOUR-ORDER-123"}'
<?php
$ch = curl_init('https://www.tshirtgang.com/api/v2/LookupOrder/');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{\"api_key\":\"YOUR_API_KEY\",\"market_id1\":\"YOUR-ORDER-123\"}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
$data = json_decode($res, true);
curl_close($ch);
print_r($data);
// Node 18+ (native fetch)
const res = await fetch('https://www.tshirtgang.com/api/v2/LookupOrder/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"api_key": "YOUR_API_KEY",
"market_id1": "YOUR-ORDER-123"
})
});
const data = await res.json();
console.log(data);
# pip install requests
import requests
res = requests.post(
'https://www.tshirtgang.com/api/v2/LookupOrder/',
json={
"api_key": "YOUR_API_KEY",
"market_id1": "YOUR-ORDER-123"
}
)
print(res.json())
{
"status": "success",
"order": {
"order_id": 554321,
"market_id1": "YOUR-ORDER-123",
"status": "printing",
"shipping": {
"fullname": "Jane Doe",
"city": "Toronto",
"country": "CA"
},
"item": {
"product_id": 98765,
"size": "M",
"color": "Black",
"quantity": 1,
"price": "$11.95"
}
}
}
| Field | Type | Description |
|---|---|---|
| status | string | `success` on a valid response. |
| order | object | Full order record. |
| order.order_id | integer | Our order ID. |
| order.market_id1 | string | Your internal order ID. |
| order.status | string | One of: `unpaid`, `paid`, `printing`, `shipped`, `cancelled`. |
| order.shipping | object | Shipping address on file. |
| order.item | object | Ordered SKU snapshot (frozen at purchase time). |
Retrieve your order history, paginated and filterable by status. Returns order summaries (IDs, dates, totals, status).
| Field | Type | Description |
|---|---|---|
| api_key required | string | Your API key from /cp/api. |
| page optional | integer | Page number (1-based). Default `1`. |
| limit optional | integer | Results per page (max 100, default 50). |
| status optional | string | Filter by status: `pending` | `paid` | `printing` | `shipped` | `cancelled`. |
| since optional | string | ISO-8601 date — only orders created after this are returned. |
curl -X POST https://www.tshirtgang.com/api/v2/GetSellerHistory/ \
-H "Content-Type: application/json" \
-d '{"api_key":"YOUR_API_KEY","page":1,"status":"shipped"}'
<?php
$ch = curl_init('https://www.tshirtgang.com/api/v2/GetSellerHistory/');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{\"api_key\":\"YOUR_API_KEY\",\"page\":1,\"status\":\"shipped\"}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
$data = json_decode($res, true);
curl_close($ch);
print_r($data);
// Node 18+ (native fetch)
const res = await fetch('https://www.tshirtgang.com/api/v2/GetSellerHistory/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"api_key": "YOUR_API_KEY",
"page": 1,
"status": "shipped"
})
});
const data = await res.json();
console.log(data);
# pip install requests
import requests
res = requests.post(
'https://www.tshirtgang.com/api/v2/GetSellerHistory/',
json={
"api_key": "YOUR_API_KEY",
"page": 1,
"status": "shipped"
}
)
print(res.json())
{
"status": "success",
"total": 89,
"orders": [
{
"order_id": 554321,
"shiplist": "SL-554321",
"status": "shipped",
"total": "$14.95",
"date": "2026-04-17"
}
]
}
| Field | Type | Description |
|---|---|---|
| status | string | `success` on a valid response. |
| total | integer | Total matching orders (across all pages). |
| orders | array | Page of order summary rows. |
| orders[].order_id | integer | Our order ID. |
| orders[].shiplist | string | Shiplist grouping ID. |
| orders[].status | string | Current order status. |
| orders[].total | string | Order total in USD. |
| orders[].date | string | Order creation date (YYYY-MM-DD). |
Retrieve the current blank catalogue (style / colour / size combinations) available for printing. Supports incremental sync via `filter.lastcheck`.
| Field | Type | Description |
|---|---|---|
| api_key required | string | Your API key from /cp/api. |
| filter.style optional | string | Style name (e.g. "Gildan 5000") or numeric style ID. |
| filter.color optional | string | Colour name (e.g. "Black"). Partial matches not accepted. |
| filter.size optional | string | Size code (S, M, L, XL, 2XL, 3XL, 4XL, 5XL, 6XL). |
| filter.region optional | string | `us`, `ca`, or `europe`. Returns the catalogue for that fulfillment region. |
| filter.available optional | boolean | `true` = only in-stock rows, `false` = only unavailable rows. Omit for all. |
| filter.lastcheck optional | integer | Unix timestamp — only return products whose pricing row was updated since. |
| filter.unreleased optional | boolean | Include products not yet released to the public (default `false`). |
curl -X POST https://www.tshirtgang.com/api/v2/GetAvailableProducts/ \
-H "Content-Type: application/json" \
-d '{"api_key":"YOUR_API_KEY","filter":{"region":"us","available":"true"}}'
<?php
$ch = curl_init('https://www.tshirtgang.com/api/v2/GetAvailableProducts/');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{\"api_key\":\"YOUR_API_KEY\",\"filter\":{\"region\":\"us\",\"available\":\"true\"}}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
$data = json_decode($res, true);
curl_close($ch);
print_r($data);
// Node 18+ (native fetch)
const res = await fetch('https://www.tshirtgang.com/api/v2/GetAvailableProducts/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"api_key": "YOUR_API_KEY",
"filter": {
"region": "us",
"available": "true"
}
})
});
const data = await res.json();
console.log(data);
# pip install requests
import requests
res = requests.post(
'https://www.tshirtgang.com/api/v2/GetAvailableProducts/',
json={
"api_key": "YOUR_API_KEY",
"filter": {
"region": "us",
"available": "true"
}
}
)
print(res.json())
{
"status": "success",
"products": [
{
"style_id": 42,
"name": "Gildan 5000",
"colors": [
"Black",
"White",
"Navy"
],
"sizes": [
"S",
"M",
"L",
"XL"
]
}
]
}
| Field | Type | Description |
|---|---|---|
| status | string | `success` on a valid response. |
| products | array | List of blank products matching the filter. |
| products[].style_id | integer | Numeric style ID — pass to CreateProduct / CreateOrder. |
| products[].name | string | Human-readable style name. |
| products[].colors | string[] | Available colour names. |
| products[].sizes | string[] | Available size codes. |
Create a new product in your catalogue from a design image URL. The product is generated for every size that exists in your Pricing for the chosen style + colour. Sizes are NOT specified in the request — the system uses what you have priced.
| Field | Type | Description |
|---|---|---|
| api_key required | string | Your API key from /cp/api. |
| product.title required | string | Product title. Shown on the product page and on invoices/order summaries. |
| product.url required | string | Publicly reachable design image URL (PNG with transparency preferred, minimum 2400×3200 recommended for DTG). Must begin with `https://`. Base64-encoded image data may also be sent in this field. |
| product.style required | string | Style name (e.g. `Classic`, `Apron`, `Hoodie`, `Ladies`, `V-Neck`). Use GetAvailableProducts to list valid style names. |
| product.color required | string | Single colour name (e.g. `Black`, `Navy`, `Heather Grey`). Use GetAvailableProducts to list valid colour names for the chosen style. |
| product.category optional | string | Top-level category that helps organize products on Tshirtgang (e.g. `Various`, `Funny`, `Holiday`). |
| product.custom_category.category optional | string | Custom category name. Max 80 characters. Created on-the-fly if it doesn't already exist for your account. |
curl -X POST https://www.tshirtgang.com/api/v2/CreateProduct/ \
-H "Content-Type: application/json" \
-d '{"api_key":"YOUR_API_KEY","product":{"title":"My Product Title T Shirt","url":"https://mywebsite.com/path/to/valid/file.png","style":"Apron","color":"Black","category":"Various","custom_category":{"category":"custom category"}}}'
<?php
$ch = curl_init('https://www.tshirtgang.com/api/v2/CreateProduct/');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{\"api_key\":\"YOUR_API_KEY\",\"product\":{\"title\":\"My Product Title T Shirt\",\"url\":\"https://mywebsite.com/path/to/valid/file.png\",\"style\":\"Apron\",\"color\":\"Black\",\"category\":\"Various\",\"custom_category\":{\"category\":\"custom category\"}}}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
$data = json_decode($res, true);
curl_close($ch);
print_r($data);
// Node 18+ (native fetch)
const res = await fetch('https://www.tshirtgang.com/api/v2/CreateProduct/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"api_key": "YOUR_API_KEY",
"product": {
"title": "My Product Title T Shirt",
"url": "https://mywebsite.com/path/to/valid/file.png",
"style": "Apron",
"color": "Black",
"category": "Various",
"custom_category": {
"category": "custom category"
}
}
})
});
const data = await res.json();
console.log(data);
# pip install requests
import requests
res = requests.post(
'https://www.tshirtgang.com/api/v2/CreateProduct/',
json={
"api_key": "YOUR_API_KEY",
"product": {
"title": "My Product Title T Shirt",
"url": "https://mywebsite.com/path/to/valid/file.png",
"style": "Apron",
"color": "Black",
"category": "Various",
"custom_category": {
"category": "custom category"
}
}
}
)
print(res.json())
{
"response": {
"success": {
"product_id": "1234567",
"preview_image": "https://s3.us-east-2.amazonaws.com/path/to/your/image.png"
}
}
}
| Field | Type | Description |
|---|---|---|
| response.success.product_id | integer | Product ID — use as `product_id` in CreateOrder. |
| response.success.preview_image | string | CDN URL of the generated mockup preview image. |
Retrieve your product catalogue with pagination. Returns product details, SKU counts, and listing status.
| Field | Type | Description |
|---|---|---|
| api_key required | string | Your API key from /cp/api. |
| page optional | integer | Page number (1-based). Default `1`. |
| limit optional | integer | Results per page. Max `100`. Default `50`. |
curl -X POST https://www.tshirtgang.com/api/v2/GetSellerProducts/ \
-H "Content-Type: application/json" \
-d '{"api_key":"YOUR_API_KEY","page":1,"limit":25}'
<?php
$ch = curl_init('https://www.tshirtgang.com/api/v2/GetSellerProducts/');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{\"api_key\":\"YOUR_API_KEY\",\"page\":1,\"limit\":25}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
$data = json_decode($res, true);
curl_close($ch);
print_r($data);
// Node 18+ (native fetch)
const res = await fetch('https://www.tshirtgang.com/api/v2/GetSellerProducts/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"api_key": "YOUR_API_KEY",
"page": 1,
"limit": 25
})
});
const data = await res.json();
console.log(data);
# pip install requests
import requests
res = requests.post(
'https://www.tshirtgang.com/api/v2/GetSellerProducts/',
json={
"api_key": "YOUR_API_KEY",
"page": 1,
"limit": 25
}
)
print(res.json())
{
"response": {
"success": {
"products": [
{
"product": {
"product_id": "999912345",
"title": "My Custom Title",
"style": "Classic",
"color": "Black",
"category": "Various",
"model": "1",
"preview_image": "https://s3.us-east-2.amazonaws.com/path/to/your/image.png"
}
}
]
}
}
}
| Field | Type | Description |
|---|---|---|
| response.success.products | array | Page of product entries. Each entry is wrapped in a `product` object. |
| response.success.products[].product.product_id | string | Product ID — use as `product_id` in CreateOrder. |
| response.success.products[].product.title | string | Product title. |
| response.success.products[].product.style | string | Style name (e.g. `Classic`, `Hoodie`). |
| response.success.products[].product.color | string | Shirt colour name (e.g. `Black`). |
| response.success.products[].product.category | string | Top-level category assigned to the product. |
| response.success.products[].product.model | string | Model identifier for the product. |
| response.success.products[].product.preview_image | string | CDN URL of the front mockup preview image. |
Estimated production turnaround (in business days) for a given style, before shipping. Use this to display "Ships in X days" on your product pages.
| Field | Type | Description |
|---|---|---|
| api_key required | string | Your API key from /cp/api. |
| style_id required | integer | Style ID from GetAvailableProducts. |
curl -X POST https://www.tshirtgang.com/api/v2/GetProductLatency/ \
-H "Content-Type: application/json" \
-d '{"api_key":"YOUR_API_KEY","style_id":42}'
<?php
$ch = curl_init('https://www.tshirtgang.com/api/v2/GetProductLatency/');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{\"api_key\":\"YOUR_API_KEY\",\"style_id\":42}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);
$data = json_decode($res, true);
curl_close($ch);
print_r($data);
// Node 18+ (native fetch)
const res = await fetch('https://www.tshirtgang.com/api/v2/GetProductLatency/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"api_key": "YOUR_API_KEY",
"style_id": 42
})
});
const data = await res.json();
console.log(data);
# pip install requests
import requests
res = requests.post(
'https://www.tshirtgang.com/api/v2/GetProductLatency/',
json={
"api_key": "YOUR_API_KEY",
"style_id": 42
}
)
print(res.json())
{
"status": "success",
"style_id": 42,
"production_days": 3,
"region": "us"
}
| Field | Type | Description |
|---|---|---|
| status | string | `success` on a valid response. |
| style_id | integer | Echoed style ID. |
| production_days | integer | Expected in-house production time (excludes shipping). |
| region | string | Fulfillment region the latency applies to. |
/cp/api.