{"openapi":"3.1.0","info":{"title":"StableFlowers","description":"Send florist-delivered flowers in the US and Canada through Florist One. Pay the exact Florist One order total with x402 on Base.","version":"1.0.0","x-guidance":"# StableFlowers API\n\nStableFlowers sends real florist-delivered flowers through Florist One. Buyers pay the exact Florist One order total with x402 on Base. StableFlowers does not add a service fee.\n\nSupported payment: x402 on Base mainnet only.\n\n## Flow\n\n1. GET /api/products — browse flower products by category or product code.\n2. GET /api/delivery-dates — list available delivery dates for a recipient ZIP/postal code.\n3. POST /api/quote — calculate the exact Florist One total for flower products.\n4. POST /api/orders — pay the quoted total with x402 and place the order.\n5. GET /api/orders/{orderId} — retrieve a stored order by local ID or Florist One order number with SIWX.\n\n## Important Behavior\n\nStableFlowers supports flower products only. Do not submit tree products with code TREES.\n\nOrder pricing is dynamic. Always call /api/quote before /api/orders, then submit the same products and delivery details to /api/orders. The paid order endpoint re-validates delivery availability and total before requesting payment.\n\nFlorist One handles customer service directly. Returned confirmations include their support contact:\n- Phone: 888-610-8262\n- Text: 501-406-0358\n- Email: service@floristone.com\n\nFlorist One does not expose live delivery tracking or cancellation through the API. The order lookup endpoint returns the submitted order details, not live delivery status.\n\n## Idempotency\n\nPOST /api/orders requires clientRequestId. Reuse the same clientRequestId only for retrying the same intended order. StableFlowers uses it to prevent duplicate Florist One order placement.\n\n## Refund Credits\n\nFlorist One reports full and partial credits through a daily report. StableFlowers records these credits for manual customer refund handling.","guidance":"# StableFlowers API\n\nStableFlowers sends real florist-delivered flowers through Florist One. Buyers pay the exact Florist One order total with x402 on Base. StableFlowers does not add a service fee.\n\nSupported payment: x402 on Base mainnet only.\n\n## Flow\n\n1. GET /api/products — browse flower products by category or product code.\n2. GET /api/delivery-dates — list available delivery dates for a recipient ZIP/postal code.\n3. POST /api/quote — calculate the exact Florist One total for flower products.\n4. POST /api/orders — pay the quoted total with x402 and place the order.\n5. GET /api/orders/{orderId} — retrieve a stored order by local ID or Florist One order number with SIWX.\n\n## Important Behavior\n\nStableFlowers supports flower products only. Do not submit tree products with code TREES.\n\nOrder pricing is dynamic. Always call /api/quote before /api/orders, then submit the same products and delivery details to /api/orders. The paid order endpoint re-validates delivery availability and total before requesting payment.\n\nFlorist One handles customer service directly. Returned confirmations include their support contact:\n- Phone: 888-610-8262\n- Text: 501-406-0358\n- Email: service@floristone.com\n\nFlorist One does not expose live delivery tracking or cancellation through the API. The order lookup endpoint returns the submitted order details, not live delivery status.\n\n## Idempotency\n\nPOST /api/orders requires clientRequestId. Reuse the same clientRequestId only for retrying the same intended order. StableFlowers uses it to prevent duplicate Florist One order placement.\n\n## Refund Credits\n\nFlorist One reports full and partial credits through a daily report. StableFlowers records these credits for manual customer refund handling.","contact":{"name":"Merit Systems","url":"https://stableflowers.dev"}},"servers":[{"url":"https://stableflowers.dev"}],"tags":[{"name":"Delivery Dates"},{"name":"Orders"},{"name":"Products"},{"name":"Quote"}],"paths":{"/api/products":{"get":{"operationId":"products","summary":"List Florist One flower products by category or fetch a single flower product by code. Tree products are filtered out.","tags":["Products"],"parameters":[{"in":"query","name":"category","schema":{"type":"string","minLength":1}},{"in":"query","name":"code","schema":{"type":"string","minLength":1}},{"in":"query","name":"count","schema":{"default":12,"type":"integer","minimum":1,"maximum":50}},{"in":"query","name":"start","schema":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991}},{"in":"query","name":"sorttype","schema":{"type":"string","enum":["pa","pd","az","za"]}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"products":{"type":"array","items":{"type":"object","properties":{"CODE":{"type":"string"},"NAME":{"type":"string"},"DESCRIPTION":{"type":"string"},"PRICE":{"type":"number","minimum":0},"DIMENSION":{"type":"string"},"SMALL":{"type":"string","format":"uri"},"LARGE":{"type":"string","format":"uri"}},"required":["CODE","NAME","PRICE"],"additionalProperties":false}},"total":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["products","total"],"additionalProperties":false}}}}}}},"/api/delivery-dates":{"get":{"operationId":"delivery-dates","summary":"List available delivery dates for a ZIP/postal code, or check one date with yyyy-mm-dd.","tags":["Delivery Dates"],"parameters":[{"in":"query","name":"zipcode","schema":{"type":"string","minLength":3,"maxLength":12},"required":true},{"in":"query","name":"date","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"dates":{"type":"array","items":{"type":"string"}},"date_available":{"type":"boolean"}},"required":["dates"],"additionalProperties":false}}}}}}},"/api/quote":{"post":{"operationId":"quote","summary":"Calculate the exact Florist One total for flower products, including delivery charge and tax. Use this before POST /api/orders.","tags":["Quote"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"products":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"code":{"type":"string","minLength":1},"price":{"type":"number","minimum":0},"recipient":{"type":"object","properties":{"zipcode":{"type":"string","minLength":3,"maxLength":12}},"required":["zipcode"]}},"required":["code","price","recipient"]}}},"required":["products"]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"subtotal":{"type":"number","minimum":0},"floristone_delivery_charge":{"type":"number","minimum":0},"delivery_charge_total":{"type":"number","minimum":0},"floristone_tax":{"type":"number","minimum":0},"tax_total":{"type":"number","minimum":0},"discount":{"type":"number","minimum":0},"order_total":{"type":"number","minimum":0}},"required":["subtotal","floristone_delivery_charge","delivery_charge_total","floristone_tax","tax_total","discount","order_total"],"additionalProperties":false}}}}}}},"/api/orders":{"post":{"operationId":"orders_create","summary":"Pay the exact Florist One total with x402 on Base and place a partner-billed flower order. Requires clientRequestId for idempotency.","tags":["Orders"],"x-payment-info":{"price":{"mode":"dynamic","currency":"USD","min":"0","max":"300.00"},"protocols":[{"x402":{}}]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"clientRequestId":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[a-zA-Z0-9._:-]+$"},"customer":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"email":{"type":"string","maxLength":100,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"address1":{"type":"string","minLength":1,"maxLength":100},"address2":{"type":"string","maxLength":100},"city":{"type":"string","minLength":1,"maxLength":100},"state":{"type":"string","minLength":2,"maxLength":2},"country":{"type":"string","minLength":2,"maxLength":2},"phone":{"type":"string","minLength":10,"maxLength":20},"zipcode":{"type":"string","minLength":3,"maxLength":12},"ip":{"type":"string","minLength":3,"maxLength":45}},"required":["name","email","address1","address2","city","state","country","phone","zipcode"]},"products":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"code":{"type":"string","minLength":1},"price":{"type":"number","minimum":0},"deliverydate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"cardmessage":{"type":"string","minLength":1,"maxLength":200},"specialinstructions":{"type":"string","maxLength":100},"recipient":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"institution":{"type":"string","maxLength":100},"address1":{"type":"string","minLength":1,"maxLength":100},"address2":{"type":"string","maxLength":100},"city":{"type":"string","minLength":1,"maxLength":100},"state":{"type":"string","minLength":2,"maxLength":2},"country":{"type":"string","minLength":2,"maxLength":2},"phone":{"type":"string","minLength":10,"maxLength":20},"zipcode":{"type":"string","minLength":3,"maxLength":12}},"required":["name","institution","address1","address2","city","state","country","phone","zipcode"]},"eventinformation":{"type":"object","properties":{"type":{"type":"string","maxLength":100},"date":{"type":"string","maxLength":20},"time":{"type":"string","maxLength":20}}}},"required":["code","price","deliverydate","cardmessage","recipient"]}},"allowsubstitutions":{"anyOf":[{"type":"number","const":0},{"type":"number","const":1}]}},"required":["clientRequestId","customer","products","allowsubstitutions"]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"florist_one_order_number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"order_total":{"type":"number","minimum":0},"subtotal":{"type":"number","minimum":0},"delivery_charge_total":{"type":"number","minimum":0},"tax_total":{"type":"number","minimum":0},"discount":{"type":"number","minimum":0},"delivery_date":{"type":"string"},"recipient":{"type":"object","properties":{"name":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zipcode":{"type":"string"}},"required":["name","city","state","zipcode"],"additionalProperties":false},"items":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"price":{"type":"number","minimum":0}},"required":["code","price"],"additionalProperties":false}},"support":{"type":"object","properties":{"phone":{"type":"string"},"text":{"type":"string"},"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["phone","text","email"],"additionalProperties":false}},"required":["id","status","order_total","delivery_date","recipient","items","support"],"additionalProperties":false}}}},"402":{"description":"Payment Required"}}},"get":{"operationId":"orders_list","summary":"List flower orders for the signing wallet.","tags":["Orders"],"security":[{"siwx":[]}],"parameters":[{"in":"query","name":"page","schema":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991}},{"in":"query","name":"per_page","schema":{"default":20,"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"orders":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"florist_one_order_number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"order_total":{"type":"number","minimum":0},"subtotal":{"type":"number","minimum":0},"delivery_charge_total":{"type":"number","minimum":0},"tax_total":{"type":"number","minimum":0},"discount":{"type":"number","minimum":0},"delivery_date":{"type":"string"},"recipient":{"type":"object","properties":{"name":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zipcode":{"type":"string"}},"required":["name","city","state","zipcode"],"additionalProperties":false},"items":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"price":{"type":"number","minimum":0}},"required":["code","price"],"additionalProperties":false}},"support":{"type":"object","properties":{"phone":{"type":"string"},"text":{"type":"string"},"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["phone","text","email"],"additionalProperties":false}},"required":["id","status","order_total","delivery_date","recipient","items","support"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"per_page":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"total_pages":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["page","per_page","total","total_pages"],"additionalProperties":false}},"required":["orders","pagination"],"additionalProperties":false}}}},"402":{"description":"Authentication Required"}}}},"/api/orders/{orderId}":{"get":{"operationId":"orders_get","summary":"Get a stored StableFlowers order by local order ID or Florist One order number. Returns submitted order details, not live delivery tracking.","tags":["Orders"],"security":[{"siwx":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"florist_one_order_number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"order_total":{"type":"number","minimum":0},"subtotal":{"type":"number","minimum":0},"delivery_charge_total":{"type":"number","minimum":0},"tax_total":{"type":"number","minimum":0},"discount":{"type":"number","minimum":0},"delivery_date":{"type":"string"},"recipient":{"type":"object","properties":{"name":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zipcode":{"type":"string"}},"required":["name","city","state","zipcode"],"additionalProperties":false},"items":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"price":{"type":"number","minimum":0}},"required":["code","price"],"additionalProperties":false}},"support":{"type":"object","properties":{"phone":{"type":"string"},"text":{"type":"string"},"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["phone","text","email"],"additionalProperties":false}},"required":["id","status","order_total","delivery_date","recipient","items","support"],"additionalProperties":false}}}},"402":{"description":"Authentication Required"}}}}},"components":{"securitySchemes":{"siwx":{"type":"apiKey","in":"header","name":"SIGN-IN-WITH-X"}}}}