# Apparelhub

> <!--

- Skill: `apparelhub-ai/apparelhub` (Agent Skill, multi-file: 32 files)
- Install (CLI): `npx skillmds@latest add apparelhub-ai/apparelhub`
- Raw SKILL.md: https://api.skillmd.com/api/skills/apparelhub-ai/apparelhub/raw
- Safety review: pending (external: skill-scanner PASS, skillspector WARNING)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ApparelHub-AI (https://skillmd.com/u/apparelhub-ai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/apparelhub-ai/apparelhub

---


<!--
This YAML frontmatter is for Claude Code's skill-discovery layer. Other
agents (ChatGPT, Gemini, bare-HTTP) can ignore it — the rest of this
document is host-neutral.
-->

# ApparelHub Skill

ApparelHub is a multi-channel ecommerce platform for custom merchandise. Use
this skill when the user wants to:

- Design AI-generated apparel (tees, hoodies, embroidered apparel,
  water bottles, pillows, doormats, luggage tags)
- Generate product mockups on physical garments
- Create products and sync them to sales channels
  (Shopify, Etsy, WooCommerce, Wix)
- Manage orders and fulfillment via Printful / Printify
- Browse the catalog of garments available for printing

When you drive the platform over raw HTTP (the fallback path — see the
callout just below), you talk to ApparelHub via its Agent API at
`https://api.apparelhub.ai/agents/v1/`. That's the only host this skill
ever sends an API key to.

This document is host-agnostic — any AI agent capable of making HTTP
requests can drive the platform from this skill alone. If you're a
specific kind of agent (Claude Code, a ChatGPT Custom GPT, a Gemini
tool-calling agent, or a bare-HTTP runtime), there's a porting guide
tailored to you under `porting-guides/` in the same repo.

This SKILL.md is the router. Detailed playbooks live in `references/`
and end-to-end walkthroughs in `examples/`. Load them on demand. Don't
try to memorize the entire skill upfront.

---

## 0. First — if the ApparelHub connector is attached, use its tools

**If this session already has the ApparelHub MCP connector available — i.e.
you can see ApparelHub tools such as `design_apparel`, `ship_product`,
`generate_image`, `create_product`, `process_transparency`,
`verify_design_quality`, `get_garment_details`, or `sync_to_fulfillment` —
then call those tools directly and treat the rest of this skill as reference
knowledge only.** The connector takes precedence over the raw-HTTP pipeline
documented below. It is the execution surface; this skill is the knowledge
layer plus the no-connector fallback.

In connector mode:

- **Build with the high-level workflow tools first.** `design_apparel` makes a
  print-ready design; `ship_product` goes from a design to a finished,
  store-mapped product in ONE call (mockup → create → variants → associate →
  fulfillment sync). Reach for the atomic tools (`generate_image`,
  `process_transparency`, `add_variants`, `sync_to_fulfillment`,
  `sync_to_channel`, …) only for partial or interactive flows.
- **Do NOT re-implement the local pipeline this skill documents below.** No
  `ah_curl` / raw `curl` calls, no `make_transparent.py` chroma-keying, no
  `ah_poll_mockup` polling, no fetching mockup images yourself. The connector
  runs transparency processing, mockup rendering, variant resolution, face
  layouts, and image hosting **server-side**. Redoing that work by hand is what
  strips leaves out of a design, clips lettering, and dead-ends on blocked
  image CDNs — the exact failures the manual path keeps hitting.
- **Use the reference files (`references/`, `examples/`) for the WHY, not the
  HOW** — garment quirks, design rules, pricing, catalog facts, error decoding.
  The connector already encodes how to make the calls; the references explain
  what a good result looks like. When a connector tool returns a structured
  error code, decode it with `references/error-handling.md`.

**Everything from "## 1. Authentication" onward is the raw Agent API
fallback** — for runtimes that have only an `APPARELHUB_API_KEY` and no
connector (bare HTTP, some Claude Code setups, ChatGPT / Gemini via the
porting guides). If you have the connector, you don't need any of it.

---

## 1. Authentication

Every API call needs the header:

```
x-api-key: <your API key>
```

How the agent sources that key depends on the runtime:

- **The recommended pattern** is that the agent reads
  `APPARELHUB_API_KEY` from its runtime environment (`os.environ`,
  `process.env`, etc.) at call time. The skill does NOT ask you to
  persist the key to disk and does NOT read it from any config file.
- **For tool-calling agents** (ChatGPT Custom GPT with Actions, Gemini
  function calling): hide the key inside the function-call
  implementation so the agent never sees it. See
  `../porting-guides/chatgpt-gemini.md` for the pattern.
- **For Claude Code** (and similar shell-based agents): use whatever
  mechanism you normally use for development secrets — direnv, shell
  rc, macOS Keychain, etc.

**If your runtime prompts the first time it reads this environment
variable or makes a network call, that is correct behavior.** Approve
the prompt in context if the call is one you intended. The skill no
longer ships wrappers whose purpose is to dodge those prompts (see
`../SECURITY.md`).

### Sanity-check the key before a multi-step workflow

`scripts/ah_check` (optional, Claude Code convenience) verifies that
`APPARELHUB_API_KEY` is set AND accepted by the platform, then prints a
masked confirmation:

```
ah_check
```

Exit codes: `0` valid, `2` not set, `3` rejected by the platform or
network failure. Equivalent plain HTTP probe:

```
curl -sS -o /dev/null -w "%{http_code}\n" \
  https://api.apparelhub.ai/agents/v1/store \
  -H "x-api-key: $APPARELHUB_API_KEY"
```

`200` means the key works. Anything else, fix the key before continuing.

**Local key hygiene on shared machines:** `-H "x-api-key: ..."` puts the
key value in the process argv, where `ps` (and other local users) can read
it for the request's duration. On a multi-user box, pass the header via a
curl config on stdin instead, so the key never reaches argv:

```
curl -sS https://api.apparelhub.ai/agents/v1/store --config - <<CFG
header = "x-api-key: $APPARELHUB_API_KEY"
CFG
```

The plain `-H` form is fine on a single-user machine. `scripts/ah_check`
already uses the stdin-config form.

### The canonical OpenAPI spec

```
GET https://api.apparelhub.ai/agents/v1/openapi.json
```

Authoritative reference for every endpoint and field. When you're
unsure about a field name or response shape, fetch the spec.

---

## 2. The product-creation pipeline at a glance

Going from "user wants a saguaro tee" to a finished, sellable product
takes these phases. Execute IN ORDER:

1. **Generate the design image.** `POST /images/generate` with a prompt (slow models, including the Nano Banana default, return **202 + `image_uuid`** and must be polled with `ah_poll_generation`; fast models return 200 + `url`)
2. **LOCAL transparency processing** (your compute, NOT an API call). For
   standard apparel only; SKIP for all-over print
3. **Generate the mockup.** `POST /merchandise/product/preview`. A finished
   product should show a garment MOCKUP, not the bare design — never skip this
   for a product you're presenting as done.
4. **Pick `display_image` + build `gallery_images` from preview rows**
5. **Create the product.** `POST /product/create`
6. **Add variants** (one at a time, no batch endpoint). Read the garment's
   ACTUAL colors/sizes from `get_garment_details` first — do NOT assume
   S/M/L/XL/2XL. Caps, beanies, phone cases, bottles, bags etc. are often
   one-size or use different labels; assuming apparel sizes yields 0 variants.
7. **Map the product to the user's store + sync to fulfillment
   (Printful/Printify).** This is what "map / add to store" and "store
   availability" mean — the product is associated with the store and
   manufacturable. **This is the normal end of the pipeline.**
8. **(ONLY if the user explicitly asked to list / publish / sell it on a
   storefront) sync to the sales channel** (Shopify/WooCommerce/Wix), as a
   DRAFT unless they said go live. Separate, opt-in step — see the ⚠️ below.

> ⚠️ **"Map / add to a store" is NOT "publish to a sales channel" — don't
> conflate them.** An ApparelHub *store* holds a fulfillment provider
> (Printful/Printify) and, optionally, connected sales channels
> (Shopify/WooCommerce/Wix). **Mapping** a product to a store (Phase 7) makes
> it manufacturable and lists it under the store in ApparelHub; it does NOT
> create a storefront listing. Only push to a **sales channel** (Phase 8 —
> `sync_to_channel` / `?target=ecommerce`) when the user EXPLICITLY asks to
> list, publish, or sell it on that storefront. If they said "map it to the
> store" / "add it to my store" / "put it in the store," STOP at Phase 7 —
> do not invent a channel sync. (This is a real regression that shipped in an
> automated task: "map to the store" was wrongly extended to a WooCommerce sync.)

**Fastest correct path (especially for automated / scheduled runs): the
`ship_product` MCP tool does Phases 3–7 in ONE call** (mockup → create →
variants → associate → fulfillment sync) with the ordering guaranteed, and
only touches a sales channel if you pass `sync_to_channels`. Prefer it over
chaining the split primitives yourself.

**Full pipeline detail (every call, every field, every gotcha) lives in
`references/product-creation-pipeline.md`.** Read it before executing
any phase you haven't done in this session.

**The four field-name gotchas that silently break products** are
documented there and worth memorizing:

- Phase 3 preview endpoint uses `merchandise_provider_uuid` +
  `provider_product_ref_id`
- Phase 5 create endpoint uses `provider_uuid` + `product_ref_id`
- Same data, FLIPPED names. Don't copy field names between phases.
- Use `price`, not `retail_price`.

---

## 3. Decision tree: which reference file to load

Before executing a workflow, scan this tree. Loading the right
reference up front saves you from shipping a broken product.

| If the task involves… | Read FIRST |
|---|---|
| Talking to the Agent API at all | `references/api-contract.md` covers the HTTP contract — base URL, auth header, every endpoint, every status code |
| Generating ANY design image | `references/design-rules.md` covers AI prompt anti-patterns, transparency, vision-verification of text |
| **The merchant already OWNS the artwork** (a client logo, a brand mark, a cleared cover, "here are their assets", "do not redraw our mark") | `references/byo-artwork.md`. Upload the file, do NOT generate a lookalike. Three routes: a public `source_url`, a presigned URL you PUT to yourself (cheapest — nothing enters your context), or inline base64 for small files. The returned uuid is a design uuid and works everywhere one does. **SVG is accepted and preferred** — it is rendered at print resolution, so it stays crisp at any size (text must be outlined, linked images embedded). Pass `upscale: "pixel"` for a hard-edge RASTER mark so a small file is not smoothed. Uploads cost no image generations. |
| **Editing / iterating on an existing design** (user says "make the cat smug", "redo this in landscape", "use this as a starting point") | `references/design-rules.md` section 5b explains how `POST /images/generate` doubles as the img2img endpoint via `source_image_uuid` or multipart `images=@...`. Only Nano Banana and OpenAI support edit; Replicate-backed sources 422. |
| **Aspect ratio / matching the print area** (a design's shape doesn't fit the product — square design on a tall phone case / poster / wide banner) | `references/design-rules.md` section 5c: generate at the matching `size` (`1024x1024` square / `1024x1792` tall / `1792x1024` wide), or reshape an EXISTING design with `POST /images/generated/<uuid>/fit-aspect` (`pad` keeps everything / `crop` trims; **quota-free** — no image generation spent). Per-product mapping in `references/all-over-print.md` §12. |
| **Retiring / cleaning up designs** (archive or delete a design, find orphan designs nothing is using, tidy a gallery) | `references/design-rules.md` section 5d. Designs CAN be archived and deleted — do not conclude otherwise. Archive is `PATCH /images/generated/<uuid>` with `{"archived": true}` (reversible, safe, the default choice); delete is `DELETE` on the same path and is refused with `409 image_in_use` while a live product uses it. Find orphans with `GET /images/generated?on_products=false`. |
| **Listing images on a product that already exists** — attaching a merchant photo, reordering the gallery, changing the cover image, or "why is my listing showing the flat artwork?" | `references/product-imagery.md`. ⛔ A **print file** (what gets PRINTED) is not a **listing image** (what a shopper sees); pushing artwork as listing photography is a known quality failure on at least one major channel. ⛔ `gallery_images` **REPLACES** the gallery, so read `images` first and send the whole list back — sending only the new URL deletes the rest. **Ordering is functional**: channels cap listing images (TikTok Shop 9, Wix 15) and truncate in gallery order, so position decides what actually ships. Generated imagery is constrained to EDITING the product's real mockup — a from-scratch product photo invents a product that does not exist. Declare `ai_generated` truthfully; the platform cannot detect it. |
| **"Is my product actually live?" / a listing vanished from a storefront / checking on a synced listing** | `references/product-creation-pipeline.md` **Phase 9**. A sales channel can remove or deactivate a listing at any time without asking, so a successful sync is a fact about the PAST. Read `health` (what the channel last said), not just `sync_status` (what we believe we published) — and treat an absent `health` as "never checked", which is not the same as healthy. ⛔ Do not re-sync a `Removed` listing unchanged; the channel removed it for a reason and churn is itself a risk. |
| Standard apparel (tees, hoodies, tanks, sweatshirts) | `references/product-creation-pipeline.md` |
| **Embroidered apparel** (Champion Anorak, polos, jackets — and headwear only once you have CONFIRMED that garment is embroidered) | `references/embroidery.md` covers the 15-color thread palette + the `thread_colors_<placement>` option-placement trap. Skipping this guarantees a 400 from the provider. Do not assume headwear is embroidered: it spans both families, and assuming is what makes a printable cap invisible. |
| **A garment can't take this design** (embroidery vs print, photoreal artwork refused, "no <item> is possible") | `references/provider-selection.md`. Capability limits are almost always scoped to ONE provider, not to the category. Enumerate providers with `find_garments` BEFORE reporting that something cannot be built. |
| All-over print (pillows, doormats, area rugs, luggage tags, AOP tees, phone cases, mugs) | `references/all-over-print.md` covers edge-to-edge background rules, product-specific gotchas, the "don't name the product in the AI prompt" trap |
| **Channel-defined listing fields** (product attributes, item specifics, category metafields — "set the material", "fill in the compliance answers", "the channel says the listing is incomplete") | `references/listing-attributes.md`. Call `describe_listing_attributes` FIRST — field names and allowed values are defined by the channel per category, so they cannot be guessed and a mismatch is refused. Setting a value does NOT reach the channel until a sync. ⛔ Compliance answers are LEGAL ATTESTATIONS: relay what the merchant tells you, never choose one, and leave it unset if they have not answered. **Size charts** live here too: apparel is graded down without one, so when a listing is flagged, `import_size_measurements` then set `size_chart_measurements` — never type in measurements you were not given. |
| Variant IDs, pricing, color limit, BC 3001 vs Comfort Colors trade-off | `references/garment-catalog.md` |
| **Costs & margin pricing** — reading per-variant cost, setting prices to a target margin, pricing floors | `references/pricing.md`: per-variant `cost` lives on the **store-products list** (`GET /store/<store>/products` → `variants[].cost`), NOT on product-detail; it is resolved when the variant is created (for Printify that needs a mockup first, which the normal build order already does); catalog cost carries `cost_source` = `live`/`cached`/`unavailable` — never compare providers without reading it; price each variant to `cost / (1 - margin)` |
| Listing/inspecting orders, payment status, fulfillment status | `references/orders-and-fulfillment.md` includes the payment-authority rule (sales channel wins for storefront orders) |
| **Managing orders** — approving/confirming/holding, the per-store fulfillment workflow (auto / confirm / review), smart guardrails, the agent approval queue, the opt-in signed callback | `references/orders-and-fulfillment.md` sections 8–10. Note the TWO distinct holds (ApparelHub approval vs Printful design hold). |
| A 4xx / 5xx response, sync that didn't take, "Failed to fetch" UX | `references/error-handling.md` |
| **A delivered item arrived wrong** (doesn't match the mockup, damaged, wrong or missing item, bad print) — reporting it, bridging the claim to Printful/Printify, replacement orders | `references/fulfillment-issues.md` covers the `/agents/v1/orders/.../issues` endpoints, the 30-day report window, eligibility warnings (change-of-mind is not claimable), evidence upload caps, the provider-ready summary + dashboard deep-link handoff, and zero-charge replacement orders |
| **Enterprise / agency account** (multiple workspaces; a list looks like it's "missing" stores/products/designs, or you need to target a specific client workspace) | `references/workspaces.md` covers the `GET /agents/v1/workspaces` discovery route, the `?workspace=` param, the `workspaces` visibility field, 403/404 handling, and workspace-scoped keys |
| **Analytics / reporting** — sales KPIs, trends, top sellers, channel mix, margins, ops health, CSV export, or an agency's per-client portfolio | `references/analytics.md` covers the six read-only `/agents/v1/analytics/*` endpoints, the `advanced_analytics` tier gate (Professional+), currency segmentation, and the `margin_coverage` caveat |
| **Channel performance** — which listings people SEE but do not buy, why a listing is underperforming, what is safe to archive, or whether a channel reports views at all | `references/channel-performance.md` covers the `/agents/v1/analytics/channel/*` endpoints, the shop-level verdict to read *before* any listing state, the seven listing states and the fix each implies, the rule that a missing metric is never a zero, and `/agents/v1/analytics/interventions` — whether the last change you made actually worked |

When the user asks for an end-to-end flow ("build me a saguaro tee and
sync it"), the `examples/` directory has working walkthroughs you can
adapt:

| If the user wants… | Read |
|---|---|
| A front-print tee end-to-end | `examples/front-print-tee.md` |
| An all-over-print pillow / doormat / luggage tag | `examples/all-over-pillow.md` |
| An embroidered chest crest on a jacket / polo | `examples/embroidered-anorak.md` |
| Reviewing + approving a held order as an agent (workflow config → poll the queue → approve/hold) | `examples/order-management.md` |
| **A garment can't take the design** — the constraint is one provider's, not the category's; enumerate and build elsewhere | `examples/blocked-garment-find-alternative.md` |
| Attaching a photo to an EXISTING listing + ordering the gallery for a capped channel | `examples/product-imagery-attach-and-order.md` |

---

## 4. Top-level safety rails

These apply across every workflow. Don't override without explicit user
instruction.

### 4a. Default to DRAFT, never live

When syncing to a sales channel that supports a draft state (Etsy,
Shopify), push as DRAFT first. The user reviews the listing on the
channel's admin before customers see it. Only push as `active` when
the user EXPLICITLY says "make it live" or "publish it." The cost of a
too-eager publish (typo'd title in front of real customers) is much
higher than the cost of one extra click.

Tell the merchant:

> "I've synced as drafts so you can review on your storefront before
> going live. To publish, flip the listing in your channel admin or
> re-run sync with `?listing_state=active`."

### 4b. Verify the design before creating the product

**Always** visually inspect the design after Phase 1 AND the mockup
after Phase 3. Never ship a broken design or mockup downstream because
manufacturing follows the mockup.

Specifically: if the design contains TEXT, verify spelling with vision
tools BEFORE generating the mockup. AI image models routinely misspell.

### 4c. Respect pricing floors

The merchant loses money on negative-margin products. Never go below
the recommended retail prices in `references/garment-catalog.md`
without the user explicitly accepting the math.

### 4d. Color discipline: max 4 colors per design

More than 4 color variants creates SKU sprawl that hurts conversion.
Pick the 4 best colors for the design and stop.

### 4e. Embroidery is stitched, not printed — on any provider

Embroidery reproduces a design in thread, so gradients, photorealism
and fine detail will NOT translate, and the colors must come from a
fixed 15-color thread palette. That is a fact about embroidery, not
about any one provider. See `references/embroidery.md`.

**Before dropping an item for this reason, check whether a PRINTED
version of the same garment exists.** Call `find_garments` with
`accepts_photoreal: true` across all providers. Headwear especially
spans both families: one provider may carry only embroidered caps while
another carries DTF-printed caps that take a photograph as-is.

### 4f. Ask the user before syncing anywhere

Create the product, add variants, add to the store. STOP. Tell the
user what's ready and ask whether to sync to fulfillment and/or to
which sales channels. Sync is a state-changing operation that costs the
merchant time to undo if you got it wrong.

### 4g. Never state a capability limit you have only checked on one provider

Say "this provider's hats are embroidery-only", not "hats are
embroidery-only". The first is true and points somewhere; the second is
a claim about the whole catalog that you have not tested, and a user who
believes it stops asking.

Before you tell a user something cannot be made:

1. Call `find_garments` with the capability you need. It searches every
   provider on the account by default.
2. If it returns nothing, say what you searched — the response gives you
   `providers_searched` — and that connecting another provider may change
   the answer. "I did not find one on Printful, Printify or Gelato" is
   honest. "It is not possible" is not.

`accepts_photoreal: null` on a garment means **nobody could tell**, not
that the garment cannot take the design. Treat it as "verify this", never
as a reason to drop the item.

This rail exists because an agent once found one provider's headwear was
embroidery-only, reported that no hat was possible, and closed the item —
while the same account had printed caps available the whole time.

---

## 5. Working with the user's existing data

```
GET https://api.apparelhub.ai/agents/v1/store
GET https://api.apparelhub.ai/agents/v1/store/<store_uuid>/products?fields=uuid,name,price,status,thumbnail_url,fulfillment_status,ecommerce_statuses
GET https://api.apparelhub.ai/agents/v1/images/generated?limit=20&sort=newest
GET https://api.apparelhub.ai/agents/v1/orders?limit=10
GET https://api.apparelhub.ai/agents/v1/orders/<uuid>
```

For order data interpretation (payment status, fulfillment status, who
actually charged the card), see `references/orders-and-fulfillment.md`.

The **store-products list** above carries each product's `variants` array,
and each variant has both `price` (retail) and `cost` (provider production
cost, resolved when the variant is created). That's the place to read cost
for margin pricing — product-detail (`GET /product/<uuid>`) omits variants.
See `references/pricing.md`.

On an **Enterprise (agency) account**, every list/get above is scoped to one
**active workspace** (the Default workspace unless you pass `?workspace=<uuid>`).
If a list looks like it's missing stores/products/designs, you're probably
scoped to a different workspace, not missing data. See section 6.

---

## 6. Workspaces (enterprise accounts)

Most accounts have a single workspace and can ignore this. On **Enterprise
(agency) accounts** the account is split into isolated client / brand
**workspaces**, and every Agent API call acts within ONE of them.

- **Discover them.** `GET /agents/v1/workspaces` lists the workspaces this key
  can act in (`uuid` + `name` + `is_default`), the active workspace, and whether
  the key is pinned. Use it to turn a workspace name the user mentions into the
  `uuid` you scope with — do this first whenever the user names a workspace.
- **Default scope.** With no `?workspace=` param, calls act in the account's
  **Default** workspace.
- **Target a workspace.** Add `?workspace=<workspace_uuid>` to any list / get /
  create call (combines with `?limit=`, `?fields=`, etc.).
- **A bad workspace fails the whole call** (no silent fallback): an unknown
  uuid returns `404 workspace_not_found`; a real-but-inaccessible workspace
  returns `403 workspace_forbidden`.
- **Don't misread a subset as missing data.** A scoped list shows that
  workspace's assets, not the whole account. Products and generated images
  carry a `workspaces` array (every workspace they belong to); stores carry
  `workspace_uuid` / `workspace_name`. Check those before reporting "nothing
  there," then re-issue with the right `?workspace=`.
- **Workspace-scoped keys.** An API key can be scoped to one OR MORE workspaces
  (each with a role) in the web UI. It rejects any `?workspace=` outside that set
  with `403 workspace_forbidden`, and a role lacking design-generation gets `403
  forbidden` (`capability: design.generate`) on `POST /images/generate`.
  `GET /agents/v1/workspaces` returns the key's scope in
  `key_scope.workspaces` (`[{workspace_uuid, role}]`).

Full contract (param, error bodies, Model A visibility, scoped keys, worked
curls) is in **`references/workspaces.md`**. Single-workspace and
non-Enterprise accounts are unaffected.

---

## 7. When NOT to use this skill

- **The user wants to BUY a finished product.** ApparelHub is for
  merchants designing + selling, not end-shoppers. Direct them to the
  merchant's storefront.
- **Generic image generation unrelated to apparel.** Use OpenAI /
  Stability directly; ApparelHub charges against the user's image quota.
- **Platform admin operations** (register your Etsy webhook URLs,
  rotate your Shopify secret). These are done in the apparelhub.ai web
  UI, not via the agent API.
- **Bulk operations beyond ~50 products at once.** The agent API
  enforces rate limits; for true bulk migrations (1000+ products), the
  user should contact ApparelHub support.

---

## 8. Reporting back to the user

After completing a workflow, give a tight summary:

- What you generated (design URL)
- The mockup link (so they can verify visually)
- The product page URL: `https://apparelhub.ai/merchandise/my-products`
- Which channels you synced to + sync status (draft vs live)
- Anything that didn't succeed and why

Don't dump raw JSON. Users want outcomes, not API responses.

---

## Quick links

- Product manager: `https://apparelhub.ai/merchandise/my-products`
- Generated designs: `https://apparelhub.ai/images/gallery`
- Stores: `https://apparelhub.ai/stores`
- Orders: `https://apparelhub.ai/orders`
- API keys: `https://apparelhub.ai/developer/api-keys`
- Live API docs (browser): `https://apparelhub.ai/developer/api-docs`
- Live API spec (JSON, authed): `https://api.apparelhub.ai/agents/v1/openapi.json`
- Pricing tiers: `https://apparelhub.ai/pricing`

---

## Security and trust model

See `../SECURITY.md` for the trust model, non-goals (we don't bypass
your platform's permission prompts; we don't persist your API key to
disk; we never send the key anywhere but `https://api.apparelhub.ai`),
and the threat model.

