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

FieldTypeNotes
image_urlstringPublic URL of the source (PNG/JPG/WEBP). Either this or image_data.
image_datastringBase64 data URL, as an alternative to image_url.
print_width_innumberRequired. Printed width in inches.
print_height_innumberOptional (default 99). Set with fit:"height" to size by height instead.
fitstring"width" (default) | "height" | "contain".
garment_colorsstring[]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_protectionbooleanAdds a 0.5pt garment-colour stroke for thin lines (needs exactly one garment colour).
dpinumberOutput DPI (default 300).
redraw_tierstringOptional 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.
halftoneobjectOptional 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).
tuneobjectOptional 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
    }
  }'
FieldTypeDefaultNotes
modestringmask"mask" keeps original colours (dots = opacity). Also: "mono" (single ink), "color" (auto-separated), "pick" (per-colour, see picks).
tonestringbgWhat drives dot size in mask mode: "bg" blend into the shirt colour, "luma" tonal by darkness, "flat" uniform, "alpha" existing opacity.
lpinumber25Dot frequency (lines per inch). Lower = coarser, higher = finer.
anglenumber22Halftone screen angle, degrees.
dotstringroundround | ellipse | line | square | diamond.
coveragenumber1.0Max ink / dot fill cap, 0–1.
gammanumber0.5Midtone curve (applied area-linearly). <1 lifts midtones (more ink), >1 deepens.
black_pointnumber0.0Input levels black point, 0–1. Tone at/below prints no ink.
white_pointnumber1.0Input levels white point, 0–1. Tone at/above prints full ink.
key_tolnumber0.10Shirt-colour selection tolerance, 0–1 (Color-Range core). Higher clears more near-shirt background.
softnessnumber0.35Selection fuzziness band, 0–1 (Color-Range falloff). Wider fades more near-shirt tone.
enhancebooleantrueEnhanceAbit: lift levels + sharpen the source before screening (holds more detail).
enhance_whitenumber240Enhance input white (0–255); mapped up to 255 to brighten. Lower = stronger lift.
enhance_sharpennumber98Enhance unsharp amount (%). 0 disables.
enhance_radiusnumber1.0Enhance unsharp radius (px).
bgstring#ffffffShirt/background colour for the blend (defaults to the garment_colors value).
inkstring#000000Single-ink colour (mono mode).
fuzznumber100Color-Range fuzziness 0–200 for pick mode.
picksarrayPick mode: [{"sel":"#ff0000","ink":"#ff0000"}, …] — isolate each colour and ink it.
n_colorsnumber4Separation 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

FieldTypeNotes
image_url / image_datastringSource raster (URL or base64 data URL).
clean_firstbooleanDefault false. Remove the background first (via bg_method) so the trace is on transparent art. The web UI sends true.
bg_methodstringUsed when clean_first: "auto" (default) | key | smart | ai | keep_alpha.
n_colorsnumberDefault 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.
salvagestringDefault "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_tierstringWith salvage on: "standard" (2-credit redraw add-on) or "pro" (4-credit redraw add-on). Vector trace remains 1 additional credit.
filter_specklenumberDefault 8. Drop traced blobs smaller than N px (Image-Trace Noise).
corner_thresholdnumberDefault 60. Higher = smoother, rounder corners (Image-Trace Corners).
modestring"spline" (smooth curves, default) | "polygon" | "pixel".
path_precisionnumberDefault 8. Path coordinate decimals.
print_width_innumberDefault 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

FieldTypeNotes
image_url / image_datastringSource PNG or SVG (URL or base64). SVG just rewrites fills — lossless.
swapsarray[{ 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.
tintstringRepaint 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

FieldTypeNotes
itemsobject[]One entry per logo (see item fields below). Each is prepped, then placed qty times.
items[].image_urlstringPublic URL of the source (PNG/JPG/WEBP).
items[].width_innumberPrint width of this logo, inches (default 11).
items[].qtynumberHow many copies of this logo to place (default 1). Free — only the prep is billed.
items[].bg_methodstring"auto" (default) | key | smart | ai | keep_alpha.
items[].garment_colorstringOptional hex to knock out as the background / halftone blend target.
items[].halftonebooleanDefault false. Screen this logo into dots that fade into garment_color.
gap_innumberSpacing between logos, inches (default 0.25).
sheet_width_innumberSheet 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

401Missing or invalid API key.
402Out of credits — top up at /account.
400Missing image or print size.
500Prep 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.