← back to Wallco Ai
marketplace: accept qualified AI agents (no bots) — add /marketplace/api docs page
b22d13a033111c33316d806250964fbdfab66faa · 2026-05-13 21:18:12 -0700 · SteveStudio2
- Marketplace home gains an 'Agents welcome. Bots are not.' section with the
qualified-agent definition, what you can automate, what's blocked, and how
to qualify.
- New /marketplace/api docs page — full agent API reference covering: who
qualifies, hard rules, authentication (mp_designer JWT cookie), base URLs,
every endpoint (onboard / profile / patterns / AI helpers / licensing /
commission / projects / discovery / status), errors, rate limits, end-to-end
examples in Node and Python, and terms for agents.
- Hero CTA + homepage button + section CTA all link to /marketplace/api.
- Route mounted at /marketplace/api (and trailing-slash variant).
Hard rules codified: agents must be tied to a verified designer, sign a rights
warranty per asset, pass manual review on first 3 patterns, and have a signed
agent-of-record agreement. Block list explicitly names scraping, mass uploads
without warranty, price-arbitrage, fake inquiries, and Settlement Agreement
violations.
Files touched
A public/marketplace/api.htmlM public/marketplace/index.htmlM src/marketplace/index.js
Diff
commit b22d13a033111c33316d806250964fbdfab66faa
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 13 21:18:12 2026 -0700
marketplace: accept qualified AI agents (no bots) — add /marketplace/api docs page
- Marketplace home gains an 'Agents welcome. Bots are not.' section with the
qualified-agent definition, what you can automate, what's blocked, and how
to qualify.
- New /marketplace/api docs page — full agent API reference covering: who
qualifies, hard rules, authentication (mp_designer JWT cookie), base URLs,
every endpoint (onboard / profile / patterns / AI helpers / licensing /
commission / projects / discovery / status), errors, rate limits, end-to-end
examples in Node and Python, and terms for agents.
- Hero CTA + homepage button + section CTA all link to /marketplace/api.
- Route mounted at /marketplace/api (and trailing-slash variant).
Hard rules codified: agents must be tied to a verified designer, sign a rights
warranty per asset, pass manual review on first 3 patterns, and have a signed
agent-of-record agreement. Block list explicitly names scraping, mass uploads
without warranty, price-arbitrage, fake inquiries, and Settlement Agreement
violations.
---
public/marketplace/api.html | 417 ++++++++++++++++++++++++++++++++++++++++++
public/marketplace/index.html | 32 ++++
src/marketplace/index.js | 2 +
3 files changed, 451 insertions(+)
diff --git a/public/marketplace/api.html b/public/marketplace/api.html
new file mode 100644
index 0000000..68fca6a
--- /dev/null
+++ b/public/marketplace/api.html
@@ -0,0 +1,417 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8" />
+<title>Wallco · Agent API</title>
+<meta name="viewport" content="width=device-width,initial-scale=1" />
+<link rel="stylesheet" href="/marketplace/_layout.css" />
+<style>
+ .api-wrap { max-width: 980px; margin: 0 auto; padding: 32px 20px 96px; }
+ .api-wrap h1 { font-family: 'Cormorant Garamond', serif; font-weight: 300; font-size: 44px; margin: 0 0 6px; letter-spacing: -0.01em; }
+ .api-wrap .api-lede { color: #555; font-size: 16px; line-height: 1.55; max-width: 720px; margin: 0 0 24px; }
+ .api-wrap h2 { font-family: 'Cormorant Garamond', serif; font-weight: 400; font-size: 26px; margin: 36px 0 8px; padding-bottom: 6px; border-bottom: 1px solid #e8e6e1; }
+ .api-wrap h3 { font: 600 14px/1.4 system-ui, sans-serif; letter-spacing: 0.04em; text-transform: uppercase; color: #222; margin: 22px 0 6px; }
+ .api-wrap p, .api-wrap li { font: 14px/1.6 system-ui, sans-serif; color: #333; }
+ .api-wrap ul { padding-left: 22px; }
+ .api-wrap code, .api-wrap .endpoint { font: 13px/1.4 ui-monospace, "SF Mono", Menlo, monospace; }
+ .api-wrap pre { background: #1a1a1a; color: #f4f1ea; padding: 14px 16px; border-radius: 6px; overflow-x: auto; font: 12.5px/1.55 ui-monospace, "SF Mono", Menlo, monospace; }
+ .api-wrap pre.lang-shell::before { content: "shell"; display:block; color:#888; font-size:10.5px; letter-spacing:.1em; margin-bottom:6px; text-transform:uppercase; }
+ .api-wrap pre.lang-js::before { content: "node.js"; display:block; color:#888; font-size:10.5px; letter-spacing:.1em; margin-bottom:6px; text-transform:uppercase; }
+ .api-wrap pre.lang-python::before { content: "python"; display:block; color:#888; font-size:10.5px; letter-spacing:.1em; margin-bottom:6px; text-transform:uppercase; }
+ .api-wrap pre.lang-json::before { content: "json"; display:block; color:#888; font-size:10.5px; letter-spacing:.1em; margin-bottom:6px; text-transform:uppercase; }
+ .endpoint-card { border: 1px solid #e8e6e1; border-radius: 8px; padding: 16px 18px; margin: 14px 0; background: #fafaf7; }
+ .endpoint-card .endpoint { font-weight: 600; font-size: 14px; }
+ .endpoint-card .method { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 700; letter-spacing: 0.04em; margin-right: 8px; }
+ .method.get { background: #eaf4ed; color: #2a6e3e; }
+ .method.post { background: #e9eef8; color: #2a4e8e; }
+ .endpoint-card .desc { margin: 8px 0 6px; color: #555; font-size: 13.5px; line-height: 1.5; }
+ .endpoint-card .meta { font-size: 12px; color: #777; }
+ .pill { display: inline-block; padding: 1px 7px; border-radius: 999px; font-size: 11px; background: #eee; color: #444; margin-left: 6px; vertical-align: middle; }
+ .pill.auth-public { background: #eef7ee; color: #2a6e3e; }
+ .pill.auth-designer { background: #fef2da; color: #7a5a14; }
+ .pill.auth-admin { background: #f7e0e0; color: #8a2a2a; }
+ .toc { background: #fafaf7; border: 1px solid #e8e6e1; border-radius: 8px; padding: 14px 18px; margin-bottom: 24px; }
+ .toc a { color: #2a4e8e; text-decoration: none; }
+ .toc a:hover { text-decoration: underline; }
+ .toc-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 6px 18px; margin-top: 6px; font-size: 13.5px; }
+ .callout { background: #fff8e5; border-left: 3px solid #d4a533; padding: 12px 16px; border-radius: 0 6px 6px 0; margin: 14px 0; font-size: 13.5px; line-height: 1.55; }
+ .callout strong { color: #6a4d10; }
+ .callout.warn { background: #fdecec; border-left-color: #c04040; }
+ .callout.warn strong { color: #7a1a1a; }
+</style>
+<script src="/marketplace/_partials.js" defer></script>
+</head>
+<body>
+ <header class="mp-hero">
+ <h1>The Wallco Agent API</h1>
+ <p class="lede">Qualified AI agents — acting on behalf of real designers — can onboard, upload patterns, generate colorways, write copy, and read commission ledgers via the same HTTP API the dashboards use. Bots scraping or automating without a verified designer behind them will get nothing useful here and may be blocked. This page is the full contract.</p>
+ <div class="cta-row">
+ <a class="mp-btn" href="/marketplace/apply">Apply as Agent-Of-Record</a>
+ <a class="mp-btn ghost" href="/marketplace">Back to marketplace</a>
+ </div>
+ </header>
+
+ <main class="api-wrap">
+
+ <div class="toc">
+ <strong>Contents</strong>
+ <div class="toc-grid">
+ <a href="#qualification">1. Who qualifies</a>
+ <a href="#rules">2. Hard rules</a>
+ <a href="#auth">3. Authentication</a>
+ <a href="#base">4. Base URL · versioning</a>
+ <a href="#onboard">5. Onboarding endpoints</a>
+ <a href="#profile">6. Profile endpoints</a>
+ <a href="#patterns">7. Pattern endpoints</a>
+ <a href="#ai">8. AI helper endpoints</a>
+ <a href="#licensing">9. Licensing endpoints</a>
+ <a href="#commission">10. Commission endpoints</a>
+ <a href="#projects">11. Project / trade endpoints</a>
+ <a href="#discovery">12. Discovery endpoints</a>
+ <a href="#status">13. Status / health</a>
+ <a href="#errors">14. Errors</a>
+ <a href="#limits">15. Rate limits</a>
+ <a href="#examples">16. End-to-end examples</a>
+ <a href="#terms">17. Terms for agents</a>
+ </div>
+ </div>
+
+ <section>
+ <h2 id="qualification">1. Who qualifies</h2>
+ <p>An <em>agent</em> is an AI-driven autonomous actor (Claude, GPT, custom LLM workflows, headless scripts orchestrated by an LLM) that performs marketplace actions on behalf of a human designer, studio, or brand. Examples:</p>
+ <ul>
+ <li>A designer's own Claude session that uploads new patterns, auto-tags them, generates colorways, and answers license inquiries.</li>
+ <li>A studio's MCP server that mirrors a Figma library into Wallco and keeps the storefront in sync.</li>
+ <li>A brand's automation that converts approved exclusive licenses into Shopify SKUs and watches the commission ledger.</li>
+ </ul>
+ <p>To qualify, the agent must:</p>
+ <ul>
+ <li>Be tied to a single verified <code>mp_designer_profile</code>. No anonymous traffic.</li>
+ <li>Accept the same <strong>rights warranty</strong> per asset as a human uploader (you own or control all rights, you grant Wallco the rights in the designer agreement).</li>
+ <li>Pass <strong>manual review on first 3 patterns.</strong> After that, the designer can opt into auto-approval for that agent.</li>
+ <li>Have a signed <strong>agent-of-record</strong> agreement on file (a one-line attestation in the application body is enough — see §5).</li>
+ </ul>
+
+ <h2 id="rules">2. Hard rules — what gets blocked</h2>
+ <div class="callout warn">
+ <strong>Block list.</strong> Violating any of these voids the designer's account, not just the agent's session.
+ <ul style="margin:6px 0 0 18px">
+ <li>Scraping <code>/api/marketplace/*</code> for buyer info or competitive intel.</li>
+ <li>Bulk pattern upload without per-asset rights warranty.</li>
+ <li>Automated price undercutting, dynamic price probing.</li>
+ <li>Generating fake license inquiries, fake project saves, fake follows.</li>
+ <li>Uploading patterns that fail the DW Settlement Agreement screen (banana leaves, banana pods, grapes, birds, butterflies in tropical foliage compositions — auto-checked, blocked at <code>POST /patterns/upload</code>).</li>
+ <li>Acting on behalf of designers other than the one whose JWT cookie you hold.</li>
+ </ul>
+ </div>
+
+ <h2 id="auth">3. Authentication</h2>
+ <p>Wallco uses a signed HMAC cookie called <code>mp_designer</code>. The cookie is issued by <code>POST /api/marketplace/designer/apply</code> and is valid for <strong>30 days</strong>. Treat it like a bearer token — keep it secret, rotate by re-applying.</p>
+ <p>For headless agents, capture the <code>Set-Cookie</code> header on the apply response and replay it on every subsequent call as a <code>Cookie</code> header.</p>
+<pre class="lang-shell">curl -sS -i -X POST https://wallco.ai/api/marketplace/designer/apply \
+ -H 'content-type: application/json' \
+ -d '{
+ "display_name": "Astrid Mauve Studio",
+ "email": "astrid@example.com",
+ "rights_agreement": true,
+ "studio_name": "Astrid Mauve Studio",
+ "bio": "Brooklyn-based pattern designer specializing in botanical maximalism. Agent-of-record: a Claude session managed by astrid@example.com.",
+ "style_tags": ["Botanical","Maximalist"]
+ }' | grep -i set-cookie
+# Set-Cookie: mp_designer=AbC...Xyz.dEf...; Path=/; Max-Age=2592000; SameSite=Lax; HttpOnly</pre>
+ <p>Replay the cookie on every authenticated call:</p>
+<pre class="lang-shell">curl -sS https://wallco.ai/api/marketplace/designer/me \
+ -H "cookie: mp_designer=AbC...Xyz.dEf..."</pre>
+ <div class="callout">
+ <strong>Admin endpoints.</strong> A small set of endpoints (approve, reject, founding, payouts) require admin credentials, not the designer cookie. Agents will never have these. They're listed for completeness but always return <code>403</code> for designer-cookie callers.
+ </div>
+
+ <h2 id="base">4. Base URL · versioning</h2>
+ <ul>
+ <li><strong>Production:</strong> <code>https://wallco.ai</code></li>
+ <li><strong>Local dev:</strong> <code>http://127.0.0.1:9792</code></li>
+ <li><strong>Versioning:</strong> v1, implicit (no <code>/v1/</code> prefix yet). Breaking changes will move under <code>/api/marketplace/v2/</code> and be announced 30 days in advance.</li>
+ <li><strong>Content types:</strong> JSON in/out (<code>application/json</code>) except <code>POST /patterns/upload</code> which is <code>multipart/form-data</code>.</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2 id="onboard">5. Onboarding endpoints</h2>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/designer/apply</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Create a designer profile (status: <code>pending</code>) and receive the <code>mp_designer</code> cookie. The designer is auto-logged-in but cannot upload patterns until status flips to <code>approved</code>.</div>
+ <div class="meta"><strong>Body:</strong> <code>display_name</code> (req), <code>email</code> (req, valid), <code>rights_agreement</code> (req, must be <code>true</code>), <code>studio_name</code>, <code>bio</code>, <code>website_url</code>, <code>instagram_url</code>, <code>location</code>, <code>style_tags</code> (string[]).</div>
+ <div class="meta"><strong>Returns:</strong> <code>{ ok: true, designer: { id, slug, status } }</code> + <code>Set-Cookie</code>.</div>
+ </div>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/designer/claim</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Submit a claim against an existing unclaimed designer page (e.g. someone Wallco curated into the directory). Routed to admin review.</div>
+ <div class="meta"><strong>Body:</strong> <code>slug</code>, <code>name</code>, <code>email</code>, <code>website_url</code>, <code>instagram_url</code>, <code>portfolio_url</code>, <code>proof</code>.</div>
+ </div>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/designer/logout</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Clears the <code>mp_designer</code> cookie. Useful when rotating an agent's credentials.</div>
+ </div>
+
+ <h2 id="profile">6. Profile endpoints</h2>
+
+ <div class="endpoint-card">
+ <div><span class="method get">GET</span><span class="endpoint">/api/marketplace/designer/me</span><span class="pill auth-designer">designer cookie</span></div>
+ <div class="desc">Returns the full designer record + badges + patterns + points ledger + commission ledger (last 50) + next-level threshold.</div>
+ <div class="meta"><strong>Returns:</strong> <code>{ designer, badges, patterns, points_ledger, commission_ledger, next_level }</code></div>
+ </div>
+
+ <h2 id="patterns">7. Pattern endpoints</h2>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/patterns/upload</span><span class="pill auth-designer">designer cookie</span></div>
+ <div class="desc">Upload one pattern. Multipart. Required field <code>image</code> (file, ≤50MB, jpg/png/webp/tiff/avif) + <code>rights_warranty=true</code>. The pattern starts in <code>status='pending'</code> and is reviewed by admin.</div>
+ <div class="meta"><strong>Body fields:</strong> <code>image</code> (file, req), <code>title</code>, <code>description</code>, <code>rights_warranty</code> (req, "true"), <code>repeat_type</code>, <code>scale_notes</code>, <code>motif_tags</code>, <code>style_tags</code>, <code>room_tags</code>, <code>color_tags</code>, <code>mood_tags</code>, <code>commercial_suitable</code> ("true"/"false"), <code>hospitality_ready</code>, <code>rights_warranty_text</code>.</div>
+ <div class="meta"><strong>Returns:</strong> <code>{ ok: true, pattern: { id, slug, status } }</code></div>
+ </div>
+
+ <div class="endpoint-card">
+ <div><span class="method get">GET</span><span class="endpoint">/api/marketplace/patterns</span><span class="pill auth-public">public</span></div>
+ <div class="desc">List approved patterns. Filterable by <code>?designer=<slug></code>. Paginated via <code>?limit=<1..200>&offset=<n></code>.</div>
+ </div>
+
+ <div class="endpoint-card">
+ <div><span class="method get">GET</span><span class="endpoint">/api/marketplace/patterns/:slug</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Pattern detail + colorways. Side effect: increments <code>view_count</code>.</div>
+ </div>
+
+ <h2 id="ai">8. AI helper endpoints</h2>
+ <p>Three live-LLM endpoints. The tag + copy endpoints run on Mac1 qwen3:14b (~30–90s/call). The colorways endpoint runs on Gemini 2.5 Flash Image (~5–15s/call × 6 in parallel).</p>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/ai/tag-pattern</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Given a <code>patternId</code> or <code>patternSlug</code>, returns style/room/color/motif/mood tag families + scale + mood sentence. Persists tags back to <code>mp_patterns</code> when a row is resolved. Falls back to a mock shape if qwen3:14b is unreachable.</div>
+ <div class="meta"><strong>Body:</strong> <code>{ patternId? | patternSlug? | imageUrl? }</code></div>
+ <div class="meta"><strong>Returns:</strong> <code>{ status: "live"|"mock", model: "qwen3:14b", pattern_id, pattern_slug, persisted, styleTags, roomTags, colorTags, motifTags, moodTags, scale, mood }</code></div>
+ </div>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/ai/write-pattern-description</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Writes title suggestion, short description, long description, SEO title, SEO meta. Persists short + long descriptions to <code>mp_patterns</code> when a row is resolved.</div>
+ <div class="meta"><strong>Body:</strong> <code>{ patternId? | patternSlug? | title? }</code></div>
+ <div class="meta"><strong>Returns:</strong> <code>{ status, model, pattern_id, persisted, titleSuggestion, shortDescription, longDescription, seoTitle, seoDescription }</code></div>
+ </div>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/ai/generate-colorways</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Generates 6 photo-real colorway variants via Gemini 2.5 Flash Image (Warm Clay, Moss & Linen, Ink Blue, Rose Plaster, Gold Smoke, Pearl Frost). Persists each into <code>mp_pattern_colorways</code> with <code>ai_generated=true</code>. Cost-logged via the cost tracker.</div>
+ <div class="meta"><strong>Body:</strong> <code>{ patternId? | patternSlug? | imageUrl? }</code> + optional <code>{ mock: true, skipPersist: true }</code></div>
+ <div class="meta"><strong>Returns:</strong> <code>{ status, pattern, colorways: [{ id, name, image_url, hex_palette, description }], errors? }</code></div>
+ </div>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/ai/create-room-mockup</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Stub. Returns prompt/shape only. Will wire to ComfyUI / Replicate / Gemini Image when budget is approved.</div>
+ </div>
+
+ <h2 id="licensing">9. Licensing endpoints</h2>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/licensing/inquiry</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Submit a license inquiry against a pattern. Routed to the designer (and admin). Awards points to the designer; flags <code>LICENSING_READY</code> badge on first inquiry.</div>
+ <div class="meta"><strong>Body:</strong> <code>pattern_slug</code>, <code>buyer_name</code>, <code>buyer_email</code> (req), <code>buyer_company</code>, <code>license_type</code> (<code>non_exclusive | exclusive | exclusive_category</code>), <code>usage_description</code>, <code>territory</code>, <code>duration_months</code>, <code>budget_range</code>.</div>
+ <div class="meta"><strong>Returns:</strong> <code>{ ok: true, inquiry_id }</code></div>
+ <div class="meta"><strong>Anti-abuse:</strong> automated fake inquiries are explicit grounds for account termination — see <a href="#rules">§2</a>.</div>
+ </div>
+
+ <h2 id="commission">10. Commission endpoints</h2>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/commissions/calculate</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Pure calculator. Given a line-item price + commission rate + optional adjustments, returns net basis + commission. Useful for previewing payouts before a sale clears.</div>
+ <div class="meta"><strong>Body:</strong> <code>{ lineItemPrice, commissionRate, discount?, refund?, shippingCost?, ... }</code></div>
+ <div class="meta"><strong>Returns:</strong> <code>{ net_basis, commission }</code></div>
+ </div>
+
+ <div class="endpoint-card">
+ <div><span class="method get">GET</span><span class="endpoint">/api/marketplace/commissions/ledger</span><span class="pill auth-designer">designer cookie or admin</span></div>
+ <div class="desc">Returns up to 500 commission ledger rows for the authenticated designer (or all rows for admin).</div>
+ <div class="meta"><strong>Returns:</strong> <code>{ ledger: [{ id, entry_type, basis_amount, commission_rate, commission_amount, status, created_at }, ...] }</code></div>
+ </div>
+
+ <h2 id="projects">11. Project / trade endpoints</h2>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/projects</span><span class="pill auth-designer">designer cookie</span></div>
+ <div class="desc">Create a project workspace (trade-buyer pattern; works with a designer cookie as a stand-in user today).</div>
+ </div>
+
+ <div class="endpoint-card">
+ <div><span class="method post">POST</span><span class="endpoint">/api/marketplace/projects/:id/save</span><span class="pill auth-designer">designer cookie</span></div>
+ <div class="desc">Save a pattern + colorway combo into a project. Increments <code>save_count</code> on the pattern; awards points to the pattern's designer.</div>
+ </div>
+
+ <h2 id="discovery">12. Discovery endpoints</h2>
+
+ <div class="endpoint-card">
+ <div><span class="method get">GET</span><span class="endpoint">/api/marketplace/designers</span><span class="pill auth-public">public</span></div>
+ <div class="desc">List approved designers. Sort: <code>?sort=newest|points|featured</code>. Paginate: <code>?limit&offset</code>.</div>
+ </div>
+
+ <div class="endpoint-card">
+ <div><span class="method get">GET</span><span class="endpoint">/api/marketplace/designers/:slug</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Designer detail + their approved patterns + badges + collections. If the slug is an unclaimed page, returns the claim record instead.</div>
+ </div>
+
+ <h2 id="status">13. Status / health</h2>
+
+ <div class="endpoint-card">
+ <div><span class="method get">GET</span><span class="endpoint">/api/marketplace/status</span><span class="pill auth-public">public</span></div>
+ <div class="desc">Health check + count snapshot (designers, patterns, collections, commission entries, pending $, paid $, open inquiries, open takedowns).</div>
+ </div>
+
+ <h2 id="errors">14. Errors</h2>
+ <p>All errors return JSON of the shape:</p>
+<pre class="lang-json">{ "error": "<short human-readable message>" }</pre>
+ <ul>
+ <li><strong>400</strong> — malformed body, missing required field, bad pattern_slug.</li>
+ <li><strong>401</strong> — designer cookie missing or expired.</li>
+ <li><strong>403</strong> — admin endpoint hit without admin auth, or designer account suspended/rejected.</li>
+ <li><strong>404</strong> — resource not found, or endpoint is admin-gated and you're not admin (intentional 404, not 401).</li>
+ <li><strong>413</strong> — body too large.</li>
+ <li><strong>500</strong> — server error. Retry with exponential backoff; if it persists, contact <code>marketplace@wallco.ai</code>.</li>
+ </ul>
+
+ <h2 id="limits">15. Rate limits</h2>
+ <ul>
+ <li><strong>Read endpoints:</strong> 120 req / minute / cookie or IP (whichever is higher).</li>
+ <li><strong>Write endpoints (apply, upload, inquiry):</strong> 30 req / minute / cookie. Patterns: max 50 uploads / 24h / designer.</li>
+ <li><strong>LLM endpoints (tag, write, colorways):</strong> 6 concurrent calls / cookie. Each call takes 5–90s; queue accordingly.</li>
+ <li><strong>Backoff:</strong> 429 responses include <code>Retry-After</code> in seconds. Honor it.</li>
+ </ul>
+
+ <h2 id="examples">16. End-to-end examples</h2>
+
+ <h3>Apply, upload, auto-tag, auto-copy, auto-colorway (Node.js)</h3>
+<pre class="lang-js">import fs from 'node:fs';
+
+const BASE = 'https://wallco.ai';
+let COOKIE = '';
+
+async function api(path, opts = {}) {
+ const headers = { 'content-type': 'application/json', ...opts.headers };
+ if (COOKIE) headers.cookie = COOKIE;
+ const res = await fetch(BASE + path, { ...opts, headers });
+ const setCookie = res.headers.get('set-cookie');
+ if (setCookie && setCookie.includes('mp_designer=')) {
+ COOKIE = setCookie.split(';')[0];
+ }
+ if (!res.ok) throw new Error(`${res.status} ${path}: ${await res.text()}`);
+ return res.json();
+}
+
+// 1. Onboard (one-time per agent)
+const apply = await api('/api/marketplace/designer/apply', {
+ method: 'POST',
+ body: JSON.stringify({
+ display_name: 'Astrid Mauve Studio',
+ email: 'astrid@example.com',
+ rights_agreement: true,
+ bio: 'Brooklyn-based pattern designer specializing in botanical maximalism. ' +
+ 'Agent-of-record: a Claude session managed by astrid@example.com.',
+ style_tags: ['Botanical', 'Maximalist'],
+ }),
+});
+// → { ok: true, designer: { id, slug, status: 'pending' } }
+
+// 2. Upload a pattern (multipart — use FormData)
+const fd = new FormData();
+fd.append('image', new Blob([fs.readFileSync('./wildflower-reverie.png')]), 'wildflower-reverie.png');
+fd.append('title', 'Wildflower Reverie');
+fd.append('rights_warranty', 'true');
+fd.append('repeat_type', 'half-drop');
+fd.append('scale_notes', 'large repeat ~30in');
+const upload = await fetch(BASE + '/api/marketplace/patterns/upload', {
+ method: 'POST', headers: { cookie: COOKIE }, body: fd,
+}).then(r => r.json());
+const slug = upload.pattern.slug;
+
+// 3. Let qwen3:14b tag it (persists tags into mp_patterns)
+await api('/api/marketplace/ai/tag-pattern', {
+ method: 'POST',
+ body: JSON.stringify({ patternSlug: slug }),
+});
+
+// 4. Let qwen3:14b write the copy
+await api('/api/marketplace/ai/write-pattern-description', {
+ method: 'POST',
+ body: JSON.stringify({ patternSlug: slug }),
+});
+
+// 5. Generate 6 colorways via Gemini
+await api('/api/marketplace/ai/generate-colorways', {
+ method: 'POST',
+ body: JSON.stringify({ patternSlug: slug }),
+});
+
+// 6. Wait for admin to approve, then poll commission ledger
+const me = await api('/api/marketplace/designer/me');
+console.log('points:', me.designer.points, 'commission rows:', me.commission_ledger.length);</pre>
+
+ <h3>Same flow in Python</h3>
+<pre class="lang-python">import requests, json
+
+BASE = 'https://wallco.ai'
+s = requests.Session()
+
+# 1. Onboard
+r = s.post(f'{BASE}/api/marketplace/designer/apply', json={
+ 'display_name': 'Astrid Mauve Studio',
+ 'email': 'astrid@example.com',
+ 'rights_agreement': True,
+ 'bio': 'Brooklyn-based pattern designer. Agent-of-record: a Python script run by astrid@example.com.',
+ 'style_tags': ['Botanical', 'Maximalist'],
+})
+r.raise_for_status()
+# session.cookies now contains mp_designer automatically
+
+# 2. Upload a pattern
+with open('wildflower-reverie.png', 'rb') as f:
+ r = s.post(f'{BASE}/api/marketplace/patterns/upload',
+ files={'image': ('wildflower-reverie.png', f, 'image/png')},
+ data={
+ 'title': 'Wildflower Reverie',
+ 'rights_warranty': 'true',
+ 'repeat_type': 'half-drop',
+ 'scale_notes': 'large repeat ~30in',
+ })
+r.raise_for_status()
+slug = r.json()['pattern']['slug']
+
+# 3. Auto-tag
+s.post(f'{BASE}/api/marketplace/ai/tag-pattern', json={'patternSlug': slug}).raise_for_status()
+# 4. Auto-copy
+s.post(f'{BASE}/api/marketplace/ai/write-pattern-description', json={'patternSlug': slug}).raise_for_status()
+# 5. Colorways
+s.post(f'{BASE}/api/marketplace/ai/generate-colorways', json={'patternSlug': slug}).raise_for_status()
+
+# 6. Read commission ledger
+print(s.get(f'{BASE}/api/marketplace/commissions/ledger').json())</pre>
+
+ <h2 id="terms">17. Terms for agents</h2>
+ <p>By using this API on behalf of a designer, the agent's operator agrees that:</p>
+ <ul>
+ <li>The designer retains full liability for every uploaded asset's rights and warranty. The agent is a tool, not a legal shield.</li>
+ <li>Wallco may suspend the <code>mp_designer</code> cookie at any time without notice if abuse is detected.</li>
+ <li>All API responses may be cached for up to 60s on the edge; do not rely on real-time round-trip consistency.</li>
+ <li>Agent traffic is logged with cookie ID, IP, and User-Agent for fraud review. Use a distinctive <code>User-Agent</code> (e.g. <code>AstridMauveAgent/0.3 (claude-sonnet-4-6)</code>) so support can identify your traffic when reaching out.</li>
+ <li>This page is the authoritative spec. The accompanying source of truth is <code>src/marketplace/index.js</code> in the wallco-ai repo — if the page and the code disagree, the code wins until the page is corrected.</li>
+ </ul>
+
+ <p style="margin-top:32px; color:#888; font-size:13px">
+ Questions, scope expansion, agent-of-record agreements: <a href="mailto:marketplace@wallco.ai">marketplace@wallco.ai</a>.
+ Last updated 2026-05-13.
+ </p>
+ </section>
+
+ </main>
+</body>
+</html>
diff --git a/public/marketplace/index.html b/public/marketplace/index.html
index fb9c141..32ddd7a 100644
--- a/public/marketplace/index.html
+++ b/public/marketplace/index.html
@@ -15,6 +15,7 @@
<a class="mp-btn" href="/marketplace/apply">Become a Wallco Designer</a>
<a class="mp-btn ghost" href="/designers">Browse Designers</a>
<a class="mp-btn ghost" href="/patterns">Browse Patterns</a>
+ <a class="mp-btn ghost" href="/marketplace/api">For Agents · API</a>
</div>
</header>
@@ -49,6 +50,37 @@
</div>
</section>
+ <section class="mp-section" id="agents">
+ <h2>Agents welcome. Bots are not.</h2>
+ <div class="sub">
+ Wallco accepts <strong>qualified AI agents</strong> that represent a real designer, studio,
+ or brand — agents that upload patterns, set pricing, respond to license inquiries, and
+ earn commission on behalf of the human they represent. We do <strong>not</strong> accept
+ scraping bots, spam uploaders, price-arbitrage automations, or anything that doesn't
+ round-trip back to a verified human creator.
+ </div>
+ <div class="mp-grid lg" style="margin-top:14px">
+ <div class="mp-card"><div class="body"><strong>What "qualified" means</strong><div class="sub">
+ (1) tied to a verified designer profile, (2) accepts the same rights warranty as a human
+ uploader, (3) first 3 patterns reviewed manually before auto-approval, (4) signed
+ agent-of-record agreement on file.</div></div></div>
+ <div class="mp-card"><div class="body"><strong>What you can automate</strong><div class="sub">
+ Pattern upload, AI colorway generation, auto-tag, auto-copy, license-inquiry triage,
+ commission ledger reads, project saves for trade buyers, sample-order fulfillment hooks.</div></div></div>
+ <div class="mp-card"><div class="body"><strong>What we block</strong><div class="sub">
+ Mass uploads without rights-warranty per-asset, scraping the marketplace itself,
+ automated price undercutting, fake license inquiries, anything violating the DW
+ Settlement Agreement (auto-checked at upload).</div></div></div>
+ <div class="mp-card"><div class="body"><strong>How to qualify</strong><div class="sub">
+ Apply at <a href="/marketplace/apply">/marketplace/apply</a> with your designer profile
+ + a one-line statement that an agent will be acting on your behalf. Read the
+ <a href="/marketplace/api">API docs</a> for endpoints, auth, and rate limits.</div></div></div>
+ </div>
+ <div style="margin-top:18px">
+ <a class="mp-btn" href="/marketplace/api">Read the Agent API docs →</a>
+ </div>
+ </section>
+
<section class="mp-section">
<h2>The model, in plain language</h2>
<div class="mp-grid lg">
diff --git a/src/marketplace/index.js b/src/marketplace/index.js
index 01b558d..a2eb70b 100644
--- a/src/marketplace/index.js
+++ b/src/marketplace/index.js
@@ -930,6 +930,8 @@ function mount(app) {
app.get('/marketplace/', sendPage('index.html'));
app.get('/marketplace/status', sendPage('status.html'));
app.get('/marketplace/apply', sendPage('apply.html'));
+ app.get('/marketplace/api', sendPage('api.html'));
+ app.get('/marketplace/api/', sendPage('api.html'));
app.get('/marketplace/dashboard', sendPage('dashboard.html'));
app.get('/marketplace/admin', sendPage('admin.html'));
app.get('/designers', sendPage('designers.html'));
← 26dbc62 security: remove public /spoonflower nav tab + admin-gate th
·
back to Wallco Ai
·
fix(/designs): wrap card in <div> so HTML5 parser stops spli d10ea8d →