API
Turn artwork into a print-ready file and get back a signed URL to the clean result. /v1/prep → 300 DPI transparent DTF PNG, /v1/vectorize → vector SVG, /v1/recolor → colour swap / tint, and /v1/gangsheet → many logos on one 21" sheet. Standard operations cost 1 credit (gang sheets: 1 per logo). AI Redraw costs 2 credits Standard or 4 Pro — same price on vectorize, trace included.
Authentication & credits
Send your key as a bearer token. Generate keys in your account → API keys (shown once). Each successful standard operation costs 1 credit. AI Redraw is 2 credits Standard / 4 Pro. Buy credits on the same page.
Authorization: Bearer mdtf_live_...
POST /v1/prep
https://worker.majordtf.com/v1/prep
curl -X POST https://worker.majordtf.com/v1/prep \
-H "Authorization: Bearer mdtf_live_..." \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://example.com/logo.png",
"print_width_in": 11,
"salvage": "on",
"redraw_tier": "standard",
"garment_colors": ["#1a1a1a"],
"thickness_protection": false
}'Request body
| Field | Type | Notes |
|---|---|---|
| image_url | string | Public URL of the source (PNG/JPG/WEBP). Either this or image_data. |
| image_data | string | Base64 data URL, as an alternative to image_url. |
| print_width_in | number | Required. Printed width in inches. |
| print_height_in | number | Optional (default 99). Set with fit:"height" to size by height instead. |
| fit | string | "width" (default) | "height" | "contain". |
| garment_colors | string[] | Pass one hex colour to key it out (removed from the design). With a halftone, that one colour is also what the dots blend/knock out against. Omit (or none) to auto-remove the background and keep every colour. |
| thickness_protection | boolean | Adds a 0.5pt garment-colour stroke for thin lines (needs exactly one garment colour). |
| dpi | number | Output DPI (default 300). |
| redraw_tier | string | Optional AI redraw tier: "standard" (2 credits, fast faithful redraw) or "pro" (4 credits, deepest reconstruction & best text fidelity). Set salvage:"on" to request it. Billing is derived from the redraw that actually runs. |
| halftone | object | Optional halftone config — see Halftone options below. Pass it with one garment_colors value to run the single-pass flat-bg halftone (Photoshop Color-Range select + screen + knockout). |
| tune | object | Optional advanced pipeline knobs (background-removal thresholds, edge despill, upscale). Defaults match the admin recipe. |
Response
{
"status": "ok",
"file_url": "https://…supabase.co/…/clean.png?token=…", // clean, full-res, 24h
"width": 3300,
"height": 4436,
"print_in": { "w": 11.0, "h": 14.79 },
"method": "ai",
"quality": "clean",
"halftoned": false,
"thin_lines": false,
"thin_pct": 0.0,
"credits_charged": 1,
"balance": 41
}file_url is a clean, un-watermarked, 24-hour signed URL. thin_lines flags sub-1 pt strokes that risk poor DTF adhesion — re-run with thickness_protection.
Idempotency
Send an Idempotency-Key header to make retries free. A repeat of the same key within 24 hours returns the original result with credits_charged: 0 and idempotent_replay: true — the pipeline doesn't re-run and you aren't billed again. Use a fresh key per distinct job; reuse it when an agent retries the same one.
-H "Idempotency-Key: <your-unique-id>"
Halftone options
Send a halftone object to screen the artwork into dots. Pass one garment_colors value and the prep runs a single pass — Color-Range select that shirt colour, tonal-screen the design (keeping its colours), knock the shirt colour out, and trim. Omit a field to use the default below.
curl -X POST https://worker.majordtf.com/v1/prep \
-H "Authorization: Bearer mdtf_live_..." \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://example.com/art.png",
"print_width_in": 11,
"garment_colors": ["#000000"],
"halftone": {
"lpi": 25, "angle": 22, "dot": "round",
"gamma": 0.5, "key_tol": 0.10, "softness": 0.35,
"enhance": true
}
}'| Field | Type | Default | Notes |
|---|---|---|---|
| mode | string | mask | "mask" keeps original colours (dots = opacity). Also: "mono" (single ink), "color" (auto-separated), "pick" (per-colour, see picks). |
| tone | string | bg | What drives dot size in mask mode: "bg" blend into the shirt colour, "luma" tonal by darkness, "flat" uniform, "alpha" existing opacity. |
| lpi | number | 25 | Dot frequency (lines per inch). Lower = coarser, higher = finer. |
| angle | number | 22 | Halftone screen angle, degrees. |
| dot | string | round | round | ellipse | line | square | diamond. |
| coverage | number | 1.0 | Max ink / dot fill cap, 0–1. |
| gamma | number | 0.5 | Midtone curve (applied area-linearly). <1 lifts midtones (more ink), >1 deepens. |
| black_point | number | 0.0 | Input levels black point, 0–1. Tone at/below prints no ink. |
| white_point | number | 1.0 | Input levels white point, 0–1. Tone at/above prints full ink. |
| key_tol | number | 0.10 | Shirt-colour selection tolerance, 0–1 (Color-Range core). Higher clears more near-shirt background. |
| softness | number | 0.35 | Selection fuzziness band, 0–1 (Color-Range falloff). Wider fades more near-shirt tone. |
| enhance | boolean | true | EnhanceAbit: lift levels + sharpen the source before screening (holds more detail). |
| enhance_white | number | 240 | Enhance input white (0–255); mapped up to 255 to brighten. Lower = stronger lift. |
| enhance_sharpen | number | 98 | Enhance unsharp amount (%). 0 disables. |
| enhance_radius | number | 1.0 | Enhance unsharp radius (px). |
| bg | string | #ffffff | Shirt/background colour for the blend (defaults to the garment_colors value). |
| ink | string | #000000 | Single-ink colour (mono mode). |
| fuzz | number | 100 | Color-Range fuzziness 0–200 for pick mode. |
| picks | array | — | Pick mode: [{"sel":"#ff0000","ink":"#ff0000"}, …] — isolate each colour and ink it. |
| n_colors | number | 4 | Separation count for color mode. |
Defaults match the MajorDTFRaster screen (25 LPI · 22° · round · gamma 0.5). Dots grow by area (Photoshop Halftone-Screen behaviour), so gamma and the levels map predictably onto printed density.
POST /v1/vectorize
Trace artwork into a clean vector SVG — a deterministic Image-Trace replica. Returns a signed .svg URL. 1 credit — or 2 Standard / 4 Pro flat when you opt into an AI redraw first (trace included).
curl -X POST https://worker.majordtf.com/v1/vectorize \
-H "Authorization: Bearer mdtf_live_..." \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://example.com/logo.png",
"clean_first": true
}'Request body
| Field | Type | Notes |
|---|---|---|
| image_url / image_data | string | Source raster (URL or base64 data URL). |
| clean_first | boolean | Default false. Remove the background first (via bg_method) so the trace is on transparent art. The web UI sends true. |
| bg_method | string | Used when clean_first: "auto" (default) | key | smart | ai | keep_alpha. |
| n_colors | number | Default 0 = auto-detect the design's own palette size (flat art traces to exactly its colours; continuous-tone art traces faithfully). >16 keeps ALL colours faithfully. 2–16 reduces to exactly that many flat colours. |
| salvage | string | Default "off" (traces the exact uploaded artwork). "auto" | "on" AI-redraw the source in flat-vector style (solid fills, hard edges), then crisp-upscale to ~4096px, before tracing — the redraw is real added edge/corner detail, so the trace runs at full resolution. "lorez" redraws with a reimagine prompt for heavily pixelated sources. |
| redraw_tier | string | With salvage on: "standard" (2-credit redraw add-on) or "pro" (4-credit redraw add-on). Vector trace remains 1 additional credit. |
| filter_speckle | number | Default 8. Drop traced blobs smaller than N px (Image-Trace Noise). |
| corner_threshold | number | Default 60. Higher = smoother, rounder corners (Image-Trace Corners). |
| mode | string | "spline" (smooth curves, default) | "polygon" | "pixel". |
| path_precision | number | Default 8. Path coordinate decimals. |
| print_width_in | number | Default 11. Only used when clean_first (scale before tracing). |
Response
{
"status": "ok",
"file_url": "https://…supabase.co/…/trace.svg?token=…", // 24h
"bytes": 48213,
"credits_charged": 1,
"balance": 40
}POST /v1/recolor
Swap colours (e.g. white → black) or tint the whole design to one colour. Works on a PNG or an SVG. Returns a signed URL in the same format as the source. 1 credit.
curl -X POST https://worker.majordtf.com/v1/recolor \
-H "Authorization: Bearer mdtf_live_..." \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://example.com/logo.png",
"swaps": [{ "from": "#ffffff", "to": "#000000", "tolerance": 0.16 }]
}'Request body
| Field | Type | Notes |
|---|---|---|
| image_url / image_data | string | Source PNG or SVG (URL or base64). SVG just rewrites fills — lossless. |
| swaps | array | [{ from, to, tolerance? }] hex colour swaps. tolerance 0–1 colour distance (default 0.14). Matched against the original first, so a simultaneous white↔black flip is safe. Provide swaps or tint. |
| tint | string | Repaint EVERY opaque pixel to this hex (keeps the alpha shape). Use instead of swaps for single-colour designs. |
Response
{
"status": "ok",
"file_url": "https://…supabase.co/…/recolor.png?token=…", // 24h
"ext": "png", // "svg" if the source was an SVG
"bytes": 603627,
"credits_charged": 1,
"balance": 39
}POST /v1/gangsheet
Prep several logos and lay them onto one print-ready 21" DTF gang sheet at 300 DPI — each logo at its own width × quantity, row-packed, sheet height grows to fit. Returns a signed PNG URL. 1 credit per logo — quantities are free, and nothing is charged if the sheet can't be built.
curl -X POST https://worker.majordtf.com/v1/gangsheet \
-H "Authorization: Bearer mdtf_live_..." \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "image_url": "https://example.com/a.png", "width_in": 8, "qty": 3 },
{ "image_url": "https://example.com/b.png", "width_in": 4, "qty": 2, "bg_method": "key" }
],
"gap_in": 0.25,
"sheet_width_in": 21
}'Request body
| Field | Type | Notes |
|---|---|---|
| items | object[] | One entry per logo (see item fields below). Each is prepped, then placed qty times. |
| items[].image_url | string | Public URL of the source (PNG/JPG/WEBP). |
| items[].width_in | number | Print width of this logo, inches (default 11). |
| items[].qty | number | How many copies of this logo to place (default 1). Free — only the prep is billed. |
| items[].bg_method | string | "auto" (default) | key | smart | ai | keep_alpha. |
| items[].garment_color | string | Optional hex to knock out as the background / halftone blend target. |
| items[].halftone | boolean | Default false. Screen this logo into dots that fade into garment_color. |
| gap_in | number | Spacing between logos, inches (default 0.25). |
| sheet_width_in | number | Sheet width, inches (default 21). Height grows to fit. |
Response
{
"status": "ok",
"file_url": "https://…supabase.co/…/gangsheet.png?token=…", // clean, 24h
"width": 6300,
"height": 4875,
"print_in": { "w": 21.0, "h": 16.25 },
"logos": 2,
"total_pieces": 5,
"credits_charged": 2, // 1 per logo; quantities are free
"balance": 38
}POST /v1/roster — coming soon
Number a whole team from one call: pass the roster and the lettering style, get back a file per player or a single gang sheet. In development — not callable yet. Today the same job runs in the browser at majordtf.com/roster, free.
Errors
| 401 | Missing or invalid API key. |
| 402 | Out of credits — top up at /account. |
| 400 | Missing image or print size. |
| 500 | Prep failed (bad/unreadable image). |
Command line
A pip-installable CLI (pure stdlib) wraps the same endpoint:
pip install majordtf export MAJORDTF_API_KEY=mdtf_live_... majordtf logo.png --width 11 --garment "#1a1a1a" --out ready.png
Calling from an agent? See the MCP docs.
