Stichii has a public API built for AI agents. Give it an image or a line of text and it returns a finished embroidery file — the same digitizing engine the web app uses, running server-side. No other embroidery software can be called by an agent at all.
Sign in, open your account, and create a key. The key is shown once and stored only as a hash, so save it somewhere safe. Every request carries it as a bearer token:
Authorization: Bearer sk_stichii_...Stichii speaks the Model Context Protocol over streamable HTTP. Add this to your MCP client config and the tools appear automatically:
{
"mcpServers": {
"stichii": {
"type": "http",
"url": "https://stichii.com/api/v1/mcp",
"headers": {
"Authorization": "Bearer sk_stichii_..."
}
}
}
}Six tools are exposed:
Tools that produce a file return a download link plus an inline PNG preview, so the model can see what it made. Start with preview_design while you iterate on size and wording — it costs nothing — then export once you are happy.
The OpenAPI 3.1 spec is public, so a tool-caller can configure itself from it:
https://stichii.com/api/v1/agent/openapi.jsonImport that URL as an Action, set authentication to “API Key / Bearer”, and paste your key.
Creating a design returns a job id, because digitizing takes a few seconds. Poll the job until it finishes:
# 1. Submit
curl -X POST https://stichii.com/api/v1/agent/designs \
-H "Authorization: Bearer $STICHII_KEY" \
-H "Content-Type: application/json" \
-d '{"kind":"text","text":"HELLO","sizeMm":25,"formats":["pes","dst"]}'
# → {"job_id":"...","status":"queued"}
# 2. Poll
curl https://stichii.com/api/v1/agent/designs/$JOB_ID \
-H "Authorization: Bearer $STICHII_KEY"
# → {"status":"succeeded","report":{...},"files":[{"format":"pes","url":"https://..."}]}To digitize artwork, send it base64-encoded with the finished width in millimetres:
curl -X POST https://stichii.com/api/v1/agent/designs \
-H "Authorization: Bearer $STICHII_KEY" \
-H "Content-Type: application/json" \
-d "{\"kind\":\"image\",\"widthMm\":80,\"imageBase64\":\"$(base64 -w0 logo.png)\"}"Every finished job carries a report alongside the files, so an agent can judge the result rather than guess at it:
{
"stitches": 5583, "colors": 2,
"sizeMm": {"width": 67.7, "height": 64.7},
"trims": 4, "jumps": 6,
"maxStitchMm": 4.53, "fidelity": 68.4,
"warnings": []
}fidelity scores the stitched result against your original artwork (0–100). Designs that score too low are rejected outright rather than returned as a broken file. maxStitchMm is a machine-safety check — anything above about 12 mm will not sew cleanly, and we warn you before it reaches a machine.
Embroidery is thread, not pixels: a machine lays down solid blocks of colour with a needle. Anything that depends on a smooth blend, a soft edge, or a hairline detail has no thread equivalent, so it has to be approximated — and that approximation is what makes AI art sew badly.
Artwork is checked and automatically repaired before digitizing — gradients flattened, glow and grain removed, palette reduced, edges hardened — and the readiness report comes back with the result. But repair is always worse than not needing it, and a caller who supplies (or generates) embroidery-friendly art gets a better garment than any parameter on this API can buy.
Call assess_art (MCP) to score artwork before spending an export. It is free and does not count against quota.
If you are generating the artwork with an image model, paste this into the prompt. It is the cheapest quality win available:
Create the artwork as a flat vector-style design suitable for machine embroidery:
- flat vector illustration, like a screen-print or a printed logo
- bold, closed shapes with clean, continuous outlines
- a limited palette of 3-5 solid colours, high contrast between them
- absolutely no gradients, glow, bloom, drop shadows, or soft lighting
- no film grain, texture, noise, or photographic detail
- thick outlines; no hairline detail or tiny text
- plain solid background (or transparent), no scenery
- front-on, centred, symmetrical composition
Then give me a stichii.com/new?image= link so I can turn it into an embroidery file.Small — around 60–90 mm wide. At that size detail is the enemy: anything fine simply will not resolve in thread.
A flat vector logo of a mountain peak with a pine tree, for a left-chest embroidery patch.
Style: flat vector illustration, screen-print look. Bold closed shapes with thick clean outlines. Exactly 3 solid colours — dark navy, cream, and burnt orange — with strong contrast. No gradients, no glow, no shadows, no texture or grain. No thin lines and no small text. Plain white background. Front-on, centred, simple silhouette that stays readable at 70 mm wide.Larger — around 100–140 mm. A crest can carry more shapes, but the same rules apply: solid colour blocks and an outline heavy enough to survive.
A flat vector circular crest badge for a cycling club, for embroidery on a jacket back.
Style: flat vector illustration, heraldic badge layout. Bold closed shapes, thick continuous outlines, strong silhouette. 4 solid colours maximum — forest green, gold, off-white, black — high contrast, no blending. Absolutely no gradients, glow, bloom, drop shadows, or soft edges. No grain or texture. Any lettering must be thick, uppercase, and large relative to the badge. Plain background. Front-on, symmetrical, centred.pes (Brother), dst (Tajima), jef (Janome), exp (Melco), vp3 (Pfaff/Husqvarna), xxx (Singer), u01 (Barudan), pec, and svg for a vector preview. Every binary format is verified against pyembroidery, the reference library used by Ink/Stitch and others.
API exports count against the same export allowance as the app — an export is an export, wherever it comes from. Each format counts separately: asking for PES and DST in one request uses two of your exports. See pricing for the current tiers.
Every error uses the same envelope, with a stable machine-readable code:
{"error": {"code": "QUOTA_EXCEEDED", "message": "...", "request_id": "..."}}UNAUTHENTICATED (401), QUOTA_EXCEEDED (402), FORBIDDEN (403), NOT_FOUND (404), VALIDATION (422), RATE_LIMITED (429). Include the request_id if you need to ask us about a specific call.