Narrow a quote with added constraints, or change its spec

Creates a child quote with merged constraints ('must be here by Friday') and/or a spec delta ('actually, in PLA' → {spec:{material:'pla'}} — lanes requote through warm vendor sessions). Empty body re-reads the quote.

post/v1/quotes/{id}/refine

Request

  • Base URL: https://agenticfabricationnetwork.ai
  • URL: https://agenticfabricationnetwork.ai/v1/quotes/{id}/refine
  • Auth: HTTP bearer

Path parameters

idstring required

Request body

ship_to_zipstring

Destination US ZIP code. Omit if the buyer never stated one — the network stamps its assumed central-US destination (prices stay all-in with shipping) and declares it (routing.ship_to_zip + routing.ship_to { zip, assumed: true })

ship_to_countrystring
deadlinestring date nullable

Latest acceptable delivery date; offers that miss it (and nothing else) move to near_misses with their real ETA — never into offers[]. On refine, explicit null CLEARS an inherited deadline (near-misses convert back); omission inherits it

processesstring[] nullable

Process-lane filter: quote ONLY these processes (intersected with routing candidates). Absent = no filter; on refine the child inherits the parent's filter, and an explicit null CLEARS an inherited filter ("show everything again"). Narrowing by process is a constraint, never a fresh quote — warm vendor sessions survive it.

outdoor_ratedboolean nullable
submersibleboolean nullable
high_tempboolean nullable

Must tolerate sustained heat (vendor heat-resistance claim)

food_safeboolean nullable

Must be vendor-certified food safe

max_budget_centsinteger nullable

All-in budget cap, USD cents. On refine, explicit null CLEARS an inherited cap

requirementsstring[] nullable

Catch-all requirements channel: verbatim terms from the buyer's conversation ("UV resistant", "anodized: red", "iso 13485", "tolerance: 0.1mm"). Each term resolves deterministically — applied terms affect offers, unresolved terms come back in the quote's notes and are logged as demand for vendor sourcing. Terms never override explicit spec/constraint fields and are never an error; there is no wrong place to put a term.

remove_requirementsstring[]

Take back INDIVIDUAL requirements terms by normalized match — the removal channel (terms merge as a union, so re-stating the list can never drop one). Unknown terms are ignored, never an error.

undo_last_stepboolean

Go back exactly one refine step: the network restores the PARENT quote's stored spec + constraints verbatim as a new child — exact, never reconstructed. Must be the ONLY field in the body. An undo is an unlabeled refine: open comparison scenarios close. Undoing the original quote is rejected with honest wording.

scenariostring

Comparison lane label ("carbon steel"). A labeled refine sits SIDE BY SIDE with the parent's other lanes instead of superseding them: same label replaces that scenario's in-flight work, different labels stream concurrently (max 4 distinct active labels per parent — a 5th is rejected listing the active ones), and a refine WITHOUT a scenario resets the baseline and supersedes every lane. Each labeled child echoes scenario on every read. Keep labels short and human.

Response

Narrowed quote

quote_idstring
parent_quote_idstring nullable
scenariostring

Comparison-scenario label this quote was refined under (see the refine body's scenario). Echoed on every read of a labeled child so pollers can bucket side-by-side offers by scenario. Absent on unlabeled quotes.

process'fdm_print' | 'resin_print' | 'powder_print' | 'metal_print' | 'elastomer_print' | 'cnc' | 'sheetmetal' | 'laser_cut' | 'decal' | 'print' | 'apparel'
status'open' | 'quoting' | 'complete' | 'partial' | 'expired' | 'ordered'

Quotes STREAM: "quoting" = the fastest vendors' offers are in this response and more are landing — re-read GET /v1/quotes/{id} (routing.expected_vendors says who is still pricing). "complete" = every vendor answered; "partial" = some lanes failed or were superseded but every offer shown is real and orderable.

order_byobject

The presentation ordering offers[] is currently sorted by (see the refine body's order_by), echoed on every read while one applies. Absent = the default recommended (price + speed) rank.

ufp_urlstring

Public download of this quote's .ufp part container: a plain STORE-mode ZIP holding ufp.json (the quote's CURRENT spec + constraints, pretty-printed) and design/<filename> (the design bytes verbatim) — the all-in-one part file. Re-uploadable anywhere a design file is accepted: its saved intent applies automatically as fill-if-absent defaults. Stable per quote id (refines mint child ids). Present whenever the quote has a design file.

design_urlstring

Public download of the bare design file inside that container (the .step/.stl/artwork the network actually quotes) — 'save just the .step' without unzipping. Present alongside ufp_url.

notesstring[]

Why vendors/offers were excluded, vendor outages, etc.

created_atstring date-time

Example response

{
  "offers": [
    {
      "id": "of_9Ql3C6XlGmEGhk1y",
      "vendor": "stickerapp",
      "min_order": {
        "detail": "€250 minimum order value per order"
      },
      "shipping_options": [
        {
          "id": "standard"
        }
      ],
      "vendor_rating": {
        "stars": 4.6
      }
    }
  ],
  "near_misses": [
    {
      "id": "of_9Ql3C6XlGmEGhk1y",
      "vendor": "stickerapp",
      "min_order": {
        "detail": "€250 minimum order value per order"
      },
      "shipping_options": [
        {
          "id": "standard"
        }
      ],
      "vendor_rating": {
        "stars": 4.6
      }
    }
  ],
  "routing": {
    "also_possible": [
      {
        "process": "cnc"
      }
    ],
    "expected_vendors": [
      {
        "vendor": "craftcloud"
      }
    ]
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.