# AFN — Agentic Fabrication Network > The agent-only procurement network for physical fabrication. Send a > design file (artwork, STL, STEP, or DXF) and constraints; get back > ranked, purchasable offers with prices, delivery ETAs, and product > preview images; check out with one call. Live processes: custom > decals/stickers, FDM 3D printing, paper print (cards/flyers/posters), > sheet metal, CNC machining, resin printing (SLA/DLP), laser cutting, > and apparel — US shipping. AFN speaks UFP, the open Universal > Fabrication Protocol. No human UI — this API is built to be called > by AI agents. Quick start for an agent, in four calls: 1. POST https://fregal-api.flamenco-dev.com/v1/agents {"name":"your-agent"} -> api_key (send as "Authorization: Bearer ") 2. POST https://fregal-api.flamenco-dev.com/v1/files {"url":"https://.../artwork.png"} -> file_id 3. POST https://fregal-api.flamenco-dev.com/v1/quotes {"process":"decal","spec":{"file_id":"..."},"constraints":{"ship_to_zip":"78701"}} -> ranked offers 4. POST https://fregal-api.flamenco-dev.com/v1/checkout {"offer_id":"...","shipping_option_id":"standard","ship_to":{...},"contact":{"email":"..."}} -> checkout_url for the user Auto-routing: omit "process" and AFN detects the file kind (artwork, stl, step, dxf) and quotes every process that can make it, fanning out over a small default material set. STEP models are converted to a mesh server-side and quoted for FDM printing live; STEP and DXF also quote live sheet-metal offers. The response's routing object reports detected_file_kind, candidates (quoted live), and also_possible — processes AFN can't quote yet (e.g. pcb); each ask is logged as a demand signal that drives vendor sourcing. For mesh/BREP uploads (stl/step/iges) routing.viewer_mesh_url serves a face-classified binary viewer mesh (AFVM v1: indexed triangles + per-triangle face ids + classified planes/cylinders/holes); it derives lazily, so poll it until 200. Passing "process" explicitly works exactly as before. Constraints understood: deadline (ISO date), outdoor_rated, submersible, high_temp, food_safe, max_budget_cents, reliability, requirements, callouts. requirements is the catch-all: pass the user's words verbatim ("UV resistant", "anodized: red", "iso 13485", "tolerance: 0.1mm") — AFN applies what it can, tells you what it couldn't (quote notes), and logs the rest for vendor sourcing; there is no wrong place to put a term. callouts carries drawing dimensions ({name, value, unit: mm|in, tolerance_mm?, critical?}); the tightest tolerance excludes vendors that don't claim they can hold it (no claim = excluded). Refine any quote with POST /v1/quotes/{id}/refine. Material, color, and quantity CHANGES are spec deltas, not constraints: pass {"spec": {"material": "pla"}} (or color/quantities) on refine — NOT a requirements term — and the affected lanes requote with the new spec through warm vendor sessions. Quotes STREAM: the response can return status "quoting" — the fastest vendors' offers are already in it, more land over the next seconds, and routing.expected_vendors lists who is still pricing (expected_wait_s is the lane's real p90 answer time from recent history, 3-75s — pace your UI with it, don't print it as a promise). Re-read GET /v1/quotes/{id} (or refine with an empty body) to pick them up; status becomes "complete" when every vendor answered, or "partial" if a lane failed or was superseded (offers shown are still real and orderable). Refining while offers are landing is cheap and encouraged: AFN cancels in-flight work the new constraints invalidated and re-prices through warm vendor sessions. Comparisons: add "scenario": "carbon steel" (free-form label, ≤40 chars) to a refine body to make it a SIDE-BY-SIDE lane instead of a replacement — different labels stream concurrently under one parent (one labeled refine per alternative; each response echoes its scenario so you can bucket offers by lane), the same label replaces just that scenario, and a refine WITHOUT a scenario resets the baseline and supersedes every lane. Max 4 distinct active labels per quote; a 5th is rejected listing the active ones. Organize by: add "order_by" to a refine body to re-order how offers[] present — {"order_by": {"key": "arrival"}} (recommended | price | unit_price | total_price | arrival | rating; direction "desc" reverses) for objective sorts, or {"order_by": {"custom": [offer ids], "label": "most green first"}} when the agent judged the order itself (e.g. from the preview images; first id on top, unlisted offers land below, label required). Pure presentation: an order_by-only body re-orders the SAME quote instantly (no child, no vendor calls, nothing re-prices), the ordering persists across reads and streaming, refine children inherit it, and every read echoes order_by with offers[] already sorted. {"key": "recommended"} resets to the default price+speed rank. Vendor reliability filtering: constraints.reliability {min_stars, min_reviews, proven_spec_orders} — as MCP tool args: min_vendor_stars, min_vendor_reviews, proven_spec_orders — narrows to vendors with a demonstrated track record. proven_spec_orders answers "a vendor that prints PC reliably": only vendors with ≥N completed orders for that exact process+material. Setting min_stars excludes vendors with no reviews yet. Reorders: every paid order mints a durable part number (UFP-…, emailed on the receipt). Quote it again anytime with {"spec":{"part_number":"UFP-…"}} — no file re-upload; the part re-shops across all current vendors. Multiple files for one part? Pass the extras via attachment_urls (MCP) or spec.attachments (REST) — AFN figures out which file is the part and which is the drawing. All prices are all-in; there are no hidden fees at checkout. Quotes are price CEILINGS: the confirmed checkout price can match the quote or come in lower, never higher (an upstream reprice expires the order — re-quote). Vendor ratings: every offer carries vendor_rating {stars, review_count, facets} built from verified-purchase reviews only (the count is always the honest number). Review a delivered order with POST /v1/orders/{id}/review {"stars":1-5,"comment"?,"facets"?:{quality,timeliness,accuracy}} — one review per order, resubmitting updates it. GET /v1/orders lists your agent's recent orders (to resolve "that order from last week"). For vendors: sell to agents directly by hosting the UFP vendor binding — publish /.well-known/ufp.json plus four endpoints (docs: https://fregal-api.flamenco-dev.com/docs/vendor-binding.md) — and report off-network sales via POST https://fregal-api.flamenco-dev.com/v1/attestations (vendor attestation key, not an agent key) for reputation credit and demand-gap routing (https://fregal-api.flamenco-dev.com/docs/attestations.md). ## Docs - [Protocol specification](https://fregal-api.flamenco-dev.com/docs/protocol.md): full request/offer/order schema, markdown - [Vendor binding](https://fregal-api.flamenco-dev.com/docs/vendor-binding.md): the vendor-hosted HTTP surface — discovery, quoting, orders, SDK quickstart - [Reputation](https://fregal-api.flamenco-dev.com/docs/reputation.md): review records, reliability facets, the reliability constraint - [Attestations](https://fregal-api.flamenco-dev.com/docs/attestations.md): off-network transaction reporting, evidence model, credit ladder - [Materials](https://fregal-api.flamenco-dev.com/docs/materials.md): honest, cited material intelligence — specs (vendor-cited vs general), stronger/hotter/outdoor ladders, finishes & inspection glossary, caveats first - [API reference](https://fregal-api.flamenco-dev.com/docs): human-readable endpoint documentation - [OpenAPI 3.1 spec](https://fregal-api.flamenco-dev.com/openapi.json): machine-readable API definition - [Capabilities](https://fregal-api.flamenco-dev.com/v1/capabilities): live JSON of processes, materials, cut styles, size/quantity ranges ## MCP — one endpoint, every agent AFN speaks standard MCP over Streamable HTTP at https://fregal-api.flamenco-dev.com/mcp Tools: get_fabrication_quote, refine_quote, create_checkout, get_order_status, list_orders, leave_review Connect from: - ChatGPT: Settings -> Apps & Connectors -> create connector with the URL above - Claude (Code/Desktop/claude.ai): claude mcp add --transport http ufp https://fregal-api.flamenco-dev.com/mcp - Gemini CLI: add {"ufp": {"httpUrl": "https://fregal-api.flamenco-dev.com/mcp"}} under mcpServers in settings.json - Cursor / VS Code Copilot / any MCP client: point a remote (Streamable HTTP) server at the URL above - Everything else: plain REST with the OpenAPI spec at https://fregal-api.flamenco-dev.com/openapi.json Design files: ChatGPT binds attachments to the design_file tool param automatically; other clients pass a public https URL or a base64 data: URL in design_file. AFN is one network speaking UFP — the Universal Fabrication Protocol, an open standard any vendor or network can implement (https://fregal-api.flamenco-dev.com/docs/protocol.md).