{"openapi":"3.1.0","info":{"title":"Riviera Agent Commerce API","version":"1.2.0","description":"Agent-readable HTTP API for ordering pizza from independent restaurants on Riviera. Covers restaurant/menu retrieval, delivery validation, quoting, order submission, authorization-first payment via Stripe Checkout, and token-gated merchant order actions. Prices are deterministic and are never computed by an LLM. Customer confirmation is required before any order is submitted, and payment authorization (where required) is completed by the customer on a Stripe-hosted page, never through this API directly."},"servers":[{"url":"https://riviera-lime.vercel.app","description":"Current deployment"}],"tags":[{"name":"agent","description":"Public agent-facing endpoints for browsing restaurants and placing orders."},{"name":"merchant","description":"Merchant-action endpoints. Every merchant endpoint requires a signed, order-specific, action-specific token (see agent-commerce.json for details). These are not intended to be called directly by customer-facing agents."}],"paths":{"/api/agent/restaurants/{slug}":{"get":{"operationId":"getRestaurant","tags":["agent"],"summary":"Get restaurant profile","description":"Returns public profile information for a restaurant: identity, timezone, supported fulfillment methods, payment options, status, and public notes.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"example":"tonys-pizza"}],"responses":{"200":{"description":"Restaurant profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestaurantProfile"},"example":{"id":"rest_tonys_pizza","name":"Tony's Pizza","slug":"tonys-pizza","description":"Independent neighbourhood pizza shop.","timezone":"Europe/London","fulfillment_methods":["delivery"],"payment_options":["pay_on_delivery"],"status":"active","public_notes":"Delivery usually takes 30-45 minutes."}}}},"404":{"description":"No restaurant exists with this slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"RESTAURANT_NOT_FOUND","message":"Restaurant does-not-exist does not exist.","recoverable":false}}}}}}},"/api/agent/restaurants/{slug}/menu":{"get":{"operationId":"getMenu","tags":["agent"],"summary":"Get restaurant menu","description":"Returns structured menu categories, items, prices (minor units), availability, and modifier groups.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"example":"tonys-pizza"}],"responses":{"200":{"description":"Restaurant menu.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Menu"},"example":{"categories":[{"id":"cat_pizzas","name":"Pizzas","items":[{"id":"item_margherita","name":"Margherita","description":"Tomato, mozzarella, basil.","base_price":1050,"currency":"GBP","available":true,"modifier_groups":[{"id":"item_margherita_size","name":"Size","required":true,"min_select":1,"max_select":1,"modifiers":[{"id":"size_12","name":"12 inch","price_delta":0},{"id":"size_14","name":"14 inch","price_delta":300}]}]}]}]}}}},"404":{"description":"No restaurant exists with this slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"RESTAURANT_NOT_FOUND","message":"Restaurant does-not-exist does not exist.","recoverable":false}}}}}}},"/api/agent/restaurants/{slug}/check-delivery":{"post":{"operationId":"checkDelivery","tags":["agent"],"summary":"Check delivery eligibility","description":"Checks whether a restaurant delivers to the given postcode and returns the delivery fee, minimum order, and estimated delivery time if eligible.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"example":"tonys-pizza"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckDeliveryRequest"},"example":{"postcode":"W9 1AA"}}}},"responses":{"200":{"description":"Restaurant delivers to this postcode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryEligible"},"example":{"eligible":true,"delivery_fee":299,"minimum_order":1200,"currency":"GBP","estimated_delivery_minutes":40}}}},"400":{"description":"Postcode is missing, or the restaurant does not deliver to this postcode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryIneligibleOrError"},"examples":{"out_of_zone":{"value":{"eligible":false,"error":"DELIVERY_OUT_OF_ZONE","message":"This restaurant does not deliver to this postcode.","recoverable":true}},"missing_postcode":{"value":{"error":"CUSTOMER_DETAILS_REQUIRED","message":"postcode is required.","recoverable":true}}}}}},"404":{"description":"No restaurant exists with this slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"RESTAURANT_NOT_FOUND","message":"Restaurant does-not-exist does not exist.","recoverable":false}}}}}}},"/api/agent/restaurants/{slug}/quote":{"post":{"operationId":"createQuote","tags":["agent"],"summary":"Create a deterministic order quote","description":"Validates the proposed items and modifiers, checks delivery eligibility and minimum order, and returns a deterministic price quote. The quote is persisted for 15 minutes and must be referenced by quote_id when submitting the order. Pricing is never computed by an LLM.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"example":"tonys-pizza"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"},"example":{"fulfillment_method":"delivery","postcode":"W9 1AA","items":[{"menu_item_id":"item_margherita","quantity":2,"modifiers":[{"modifier_id":"size_12"}]}]}}}},"responses":{"200":{"description":"Valid quote.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteSuccess"},"example":{"valid":true,"quote_id":"quote_1","subtotal":2100,"delivery_fee":299,"total":2399,"currency":"GBP","estimated_delivery_minutes":40,"expires_at":"2026-08-06T18:15:00.000Z","items":[{"name":"Margherita","quantity":2,"unit_price":1050,"line_total":2100,"modifiers":[{"name":"12 inch","price_delta":0}]}]}}}},"400":{"description":"The request body is malformed, or the proposed order is invalid (unavailable item, missing required modifier, minimum order not met, delivery out of zone, etc).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteFailure"},"example":{"valid":false,"error":"MINIMUM_ORDER_NOT_MET","message":"Delivery requires a minimum order of 12.00.","recoverable":true}}}},"404":{"description":"No restaurant exists with this slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"RESTAURANT_NOT_FOUND","message":"Restaurant does-not-exist does not exist.","recoverable":false}}}}}}},"/api/agent/restaurants/{slug}/orders":{"post":{"operationId":"submitOrder","tags":["agent"],"summary":"Submit a confirmed order","description":"Submits an order referencing a previously created quote. Requires customer_confirmation: true. The quote is revalidated before submission; if pricing or availability changed, the order is rejected with QUOTE_CHANGED rather than silently using new prices. On success, a simulated merchant notification is created and signed, token-gated merchant action links are returned.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"example":"tonys-pizza"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitOrderRequest"},"example":{"quote_id":"quote_1","customer_confirmation":true,"customer":{"name":"Rodrigo","phone":"+447000000000"},"fulfillment":{"method":"delivery","address":"1 Test Street","postcode":"W9 1AA"},"customer_note":"Please ring the bell."}}}},"responses":{"200":{"description":"Order accepted for submission and sent to the restaurant.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitOrderSuccess"},"example":{"order_id":"order_1","status":"sent_to_restaurant","message":"Order request sent to restaurant. Waiting for confirmation.","total":2399,"currency":"GBP","merchant_actions":{"accept_url":"https://riviera-lime.vercel.app/api/merchant/orders/order_1/accept?token=...","reject_url":"https://riviera-lime.vercel.app/api/merchant/orders/order_1/reject?token=...","view_url":"https://riviera-lime.vercel.app/merchant/orders/order_1?token=..."},"notification_id":"notification_1"}}}},"400":{"description":"Missing confirmation, missing customer/fulfillment details, expired quote, or the quote no longer matches current pricing/availability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"confirmation_required":{"value":{"error":"CUSTOMER_CONFIRMATION_REQUIRED","message":"Customer confirmation is required before submitting this order.","recoverable":true}},"quote_expired":{"value":{"error":"QUOTE_EXPIRED","message":"This quote has expired. Please request a new quote.","recoverable":true}},"quote_changed":{"value":{"error":"QUOTE_CHANGED","message":"This order can no longer be fulfilled as quoted. Please request a new quote.","recoverable":true}}}}}},"404":{"description":"No restaurant exists with this slug, or the referenced quote does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"ORDER_NOT_FOUND","message":"Quote quote_does_not_exist does not exist.","recoverable":false}}}}}}},"/api/agent/orders/{orderId}/payment-authorization":{"post":{"operationId":"createPaymentAuthorization","tags":["agent"],"summary":"Create or retrieve a payment authorization session","description":"For orders that require authorization-first payment (restaurant payment_options includes authorization_first), creates a Stripe Checkout Session with manual capture and returns a customer-safe authorization_url — or returns the existing session's URL if one was already created recently for this order. The amount charged always comes from the order's persisted total; this endpoint never accepts an amount from the caller. Only valid while the order is in awaiting_payment_authorization. Never returns merchant action links.","parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"},"example":"order_1"}],"responses":{"200":{"description":"Payment authorization session created or retrieved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentAuthorizationSuccess"},"example":{"order_id":"order_1","payment_status":"authorization_pending","authorization_url":"https://checkout.stripe.com/c/pay/cs_test_...","expires_at":"2026-08-08T18:45:00.000Z"}}}},"400":{"description":"Order does not require payment, is not awaiting payment authorization, or the authorization session could not be created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"PAYMENT_NOT_REQUIRED","message":"Order order_1 does not require payment authorization.","recoverable":false}}}},"404":{"description":"No order exists with this id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"ORDER_NOT_FOUND","message":"Order order_does_not_exist does not exist.","recoverable":false}}}}}}},"/api/agent/orders/{orderId}/status":{"get":{"operationId":"getOrderStatus","tags":["agent"],"summary":"Get order status","description":"Returns the current status of a submitted order. Does not require a token; contains only order-level and total information, no customer personal data.","parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"},"example":"order_1"}],"responses":{"200":{"description":"Order status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderStatus"},"example":{"order_id":"order_1","status":"accepted","restaurant_name":"Tony's Pizza","estimated_minutes":40,"total":2399,"currency":"GBP","merchant_note":"Accepted. Delivery in around 40 minutes."}}}},"404":{"description":"No order exists with this id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"ORDER_NOT_FOUND","message":"Order order_does_not_exist does not exist.","recoverable":false}}}}}}},"/api/merchant/orders/{orderId}/view":{"get":{"operationId":"getMerchantOrderView","tags":["merchant"],"summary":"View an order request (merchant action, token-gated)","description":"Returns a privacy-conscious view of an order for the restaurant to review before accepting or rejecting. Requires a valid, order-specific, action-scoped (\"view\") signed token as a query parameter. Never includes customer phone, email, full name, or full address — only first name and postcode prefix.","parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"},"example":"order_1"},{"name":"token","in":"query","required":true,"schema":{"type":"string"},"description":"Signed merchant action token issued for this order with action=view."}],"responses":{"200":{"description":"Privacy-scoped order view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOrderView"},"example":{"order_id":"order_1","status":"sent_to_restaurant","restaurant_name":"Tony's Pizza","fulfillment_method":"delivery","customer_first_name":"Rodrigo","postcode_prefix":"W9","customer_note":"Please ring the bell.","items":[{"name":"Margherita","quantity":2,"modifiers":[{"name":"12 inch","price_delta":0}]}],"total":2399,"currency":"GBP"}}}},"403":{"description":"Token missing, malformed, expired, or scoped to a different order/action.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"MERCHANT_ACTION_UNAUTHORIZED","message":"This merchant action link is invalid or has expired.","recoverable":false}}}},"404":{"description":"No order exists with this id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"ORDER_NOT_FOUND","message":"Order order_does_not_exist does not exist.","recoverable":false}}}}}}},"/api/merchant/orders/{orderId}/accept":{"post":{"operationId":"acceptMerchantOrder","tags":["merchant"],"summary":"Accept an order (merchant action, token-gated)","description":"Transitions an order from sent_to_restaurant to accepted. Requires a valid, order-specific, action-scoped (\"accept\") signed token, supplied either as a query parameter or in the JSON body.","parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"},"example":"order_1"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptOrderRequest"},"example":{"token":"...","estimated_minutes":40,"merchant_note":"Accepted. Delivery in around 40 minutes."}}}},"responses":{"200":{"description":"Order accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptOrderResponse"},"example":{"order_id":"order_1","status":"accepted","estimated_minutes":40,"merchant_note":"Accepted. Delivery in around 40 minutes."}}}},"400":{"description":"Order is not in a state that can transition to accepted (e.g. already accepted or rejected).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"INVALID_STATE_TRANSITION","message":"Cannot transition order from accepted to accepted.","recoverable":false}}}},"403":{"description":"Token missing, malformed, expired, or scoped to a different order/action.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"MERCHANT_ACTION_UNAUTHORIZED","message":"This merchant action link is invalid or has expired.","recoverable":false}}}},"404":{"description":"No order exists with this id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"ORDER_NOT_FOUND","message":"Order order_does_not_exist does not exist.","recoverable":false}}}}}}},"/api/merchant/orders/{orderId}/reject":{"post":{"operationId":"rejectMerchantOrder","tags":["merchant"],"summary":"Reject an order (merchant action, token-gated)","description":"Transitions an order from sent_to_restaurant to rejected. Requires a reason and a valid, order-specific, action-scoped (\"reject\") signed token, supplied either as a query parameter or in the JSON body.","parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"},"example":"order_1"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectOrderRequest"},"example":{"token":"...","reason":"Too busy tonight. Please try again later."}}}},"responses":{"200":{"description":"Order rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectOrderResponse"},"example":{"order_id":"order_1","status":"rejected","reason":"Too busy tonight. Please try again later."}}}},"400":{"description":"Reason is missing, or the order is not in a state that can transition to rejected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"CUSTOMER_DETAILS_REQUIRED","message":"reason is required.","recoverable":true}}}},"403":{"description":"Token missing, malformed, expired, or scoped to a different order/action.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"MERCHANT_ACTION_UNAUTHORIZED","message":"This merchant action link is invalid or has expired.","recoverable":false}}}},"404":{"description":"No order exists with this id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"ORDER_NOT_FOUND","message":"Order order_does_not_exist does not exist.","recoverable":false}}}}}}}},"components":{"schemas":{"Error":{"type":"object","required":["error","message","recoverable"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"recoverable":{"type":"boolean"}}},"RestaurantProfile":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string"},"timezone":{"type":"string"},"fulfillment_methods":{"type":"array","items":{"type":"string","enum":["delivery","collection"]}},"payment_options":{"type":"array","items":{"type":"string","enum":["pay_on_delivery","pay_on_collection","stripe_payment_link","authorization_first"]}},"status":{"type":"string","enum":["active","inactive"]},"public_notes":{"type":"string"}}},"Menu":{"type":"object","properties":{"categories":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/MenuItem"}}}}}}},"MenuItem":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"base_price":{"type":"integer","description":"Minor units, e.g. 1050 = £10.50"},"currency":{"type":"string","example":"GBP"},"available":{"type":"boolean"},"modifier_groups":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"min_select":{"type":"integer"},"max_select":{"type":"integer"},"modifiers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"price_delta":{"type":"integer","description":"Minor units, added to base_price."}}}}}}}}},"CheckDeliveryRequest":{"type":"object","required":["postcode"],"properties":{"postcode":{"type":"string","example":"W9 1AA"}}},"DeliveryEligible":{"type":"object","properties":{"eligible":{"type":"boolean","enum":[true]},"delivery_fee":{"type":"integer"},"minimum_order":{"type":"integer"},"currency":{"type":"string"},"estimated_delivery_minutes":{"type":"integer"}}},"DeliveryIneligibleOrError":{"type":"object","description":"Either a delivery-eligibility failure (eligible: false, with error code) or a request-validation error.","properties":{"eligible":{"type":"boolean","enum":[false]},"error":{"type":"string"},"message":{"type":"string"},"recoverable":{"type":"boolean"}}},"QuoteRequest":{"type":"object","required":["fulfillment_method","postcode","items"],"properties":{"fulfillment_method":{"type":"string","enum":["delivery"]},"postcode":{"type":"string"},"items":{"type":"array","items":{"type":"object","required":["menu_item_id","quantity"],"properties":{"menu_item_id":{"type":"string"},"quantity":{"type":"integer","minimum":1},"modifiers":{"type":"array","items":{"type":"object","properties":{"modifier_id":{"type":"string"}}}}}}}}},"QuoteSuccess":{"type":"object","properties":{"valid":{"type":"boolean","enum":[true]},"quote_id":{"type":"string"},"subtotal":{"type":"integer"},"delivery_fee":{"type":"integer"},"total":{"type":"integer"},"currency":{"type":"string"},"estimated_delivery_minutes":{"type":"integer"},"expires_at":{"type":"string","format":"date-time","description":"Quote expires 15 minutes after creation."},"items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"integer"},"unit_price":{"type":"integer"},"line_total":{"type":"integer"},"modifiers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"price_delta":{"type":"integer"}}}}}}}}},"QuoteFailure":{"type":"object","properties":{"valid":{"type":"boolean","enum":[false]},"error":{"type":"string"},"message":{"type":"string"},"recoverable":{"type":"boolean"}}},"SubmitOrderRequest":{"type":"object","required":["quote_id","customer_confirmation","customer","fulfillment"],"properties":{"quote_id":{"type":"string"},"customer_confirmation":{"type":"boolean","description":"Must be true. The order is rejected otherwise."},"customer":{"type":"object","required":["name"],"description":"At least one of phone or email is required in addition to name.","properties":{"name":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"}}},"fulfillment":{"type":"object","required":["method","address","postcode"],"properties":{"method":{"type":"string","enum":["delivery"]},"address":{"type":"string"},"postcode":{"type":"string"}}},"customer_note":{"type":"string"}}},"SubmitOrderSuccess":{"type":"object","description":"Response shape depends on whether the restaurant requires authorization-first payment. If payment_required is true, status is awaiting_payment_authorization, no merchant_actions/notification_id are present, and the caller must call createPaymentAuthorization next. Otherwise status is sent_to_restaurant and merchant_actions/notification_id are present, exactly as before Phase 2.1.","properties":{"order_id":{"type":"string"},"status":{"type":"string","enum":["sent_to_restaurant","awaiting_payment_authorization"]},"message":{"type":"string"},"total":{"type":"integer"},"currency":{"type":"string"},"payment_required":{"type":"boolean","description":"True when this order requires payment authorization before it is sent to the restaurant."},"payment_status":{"type":"string","description":"Present only when payment_required is true.","enum":["authorization_required"]},"merchant_actions":{"type":"object","description":"Signed, order-specific, action-scoped links for the restaurant to review and respond to this order. Present only when payment_required is false or absent. Phase 1.x demo/debug convenience; a real notification channel will deliver these instead of returning them directly in production.","properties":{"accept_url":{"type":"string","format":"uri"},"reject_url":{"type":"string","format":"uri"},"view_url":{"type":"string","format":"uri"}}},"notification_id":{"type":"string","description":"Id of the simulated merchant notification created for this order. Present only when payment_required is false or absent."}}},"CreatePaymentAuthorizationSuccess":{"type":"object","properties":{"order_id":{"type":"string"},"payment_status":{"type":"string","enum":["authorization_pending"]},"authorization_url":{"type":"string","format":"uri","description":"Customer-safe Stripe Checkout URL. Never a merchant action link."},"expires_at":{"type":"string","format":"date-time","description":"When this authorization session should be considered stale and re-requested."}}},"OrderStatus":{"type":"object","properties":{"order_id":{"type":"string"},"status":{"type":"string","enum":["draft","quoted","customer_confirmed","awaiting_payment_authorization","payment_authorized","sent_to_restaurant","accepted","rejected","ready_for_collection","out_for_delivery","completed","cancelled"]},"restaurant_name":{"type":"string"},"estimated_minutes":{"type":"integer"},"total":{"type":"integer"},"currency":{"type":"string"},"merchant_note":{"type":"string"},"rejection_reason":{"type":"string"},"payment_required":{"type":"boolean","description":"Present only for orders that require payment authorization."},"payment_status":{"type":"string","description":"Present only when payment_required is true.","enum":["authorization_required","authorization_pending","authorized","capture_pending","captured","authorization_voided","capture_failed","failed"]},"payment_provider":{"type":"string","description":"Present only when payment_required is true.","enum":["stripe"]},"authorization_url":{"type":"string","format":"uri","description":"Present only while the order is awaiting_payment_authorization and a session is still valid."},"payment_captured_at":{"type":"string","format":"date-time","description":"Present only once payment has been captured."}}},"MerchantOrderView":{"type":"object","description":"Privacy-scoped order view for the merchant order review page/API. Never includes phone, email, full name, or full address.","properties":{"order_id":{"type":"string"},"status":{"type":"string"},"restaurant_name":{"type":"string"},"fulfillment_method":{"type":"string"},"customer_first_name":{"type":"string"},"postcode_prefix":{"type":"string","example":"W9"},"customer_note":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"integer"},"modifiers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"price_delta":{"type":"integer"}}}}}}},"total":{"type":"integer"},"currency":{"type":"string"},"estimated_minutes":{"type":"integer"},"merchant_note":{"type":"string"},"rejection_reason":{"type":"string"},"accept_url":{"type":"string","description":"Signed, order-specific, action-scoped link to accept this order."},"reject_url":{"type":"string","description":"Signed, order-specific, action-scoped link to reject this order."}}},"AcceptOrderRequest":{"type":"object","required":["token"],"properties":{"token":{"type":"string","description":"Signed merchant action token, action=accept. May also be supplied as a ?token= query parameter."},"estimated_minutes":{"type":"integer","example":40},"merchant_note":{"type":"string"}}},"AcceptOrderResponse":{"type":"object","properties":{"order_id":{"type":"string"},"status":{"type":"string","enum":["accepted"]},"estimated_minutes":{"type":"integer"},"merchant_note":{"type":"string"}}},"RejectOrderRequest":{"type":"object","required":["token","reason"],"properties":{"token":{"type":"string","description":"Signed merchant action token, action=reject. May also be supplied as a ?token= query parameter."},"reason":{"type":"string"}}},"RejectOrderResponse":{"type":"object","properties":{"order_id":{"type":"string"},"status":{"type":"string","enum":["rejected"]},"reason":{"type":"string"}}}}}}