{
  "components": {
    "schemas": {
      "Answer": {
        "properties": {
          "answer": {
            "description": "The seller's answer",
            "type": "string"
          },
          "answered": {
            "type": "boolean"
          },
          "conversation_id": {
            "description": "Pass back to keep asking",
            "type": "string"
          },
          "deal": {
            "$ref": "#/components/schemas/Deal"
          },
          "next": {
            "description": "What to do next",
            "type": "string"
          },
          "offer": {
            "$ref": "#/components/schemas/Offer"
          },
          "reason": {
            "description": "Why it was not answered",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Deal": {
        "description": "The price Ego agreed with you (only when it agreed one). Pass id as deal_id to createRequest within 24 hours; that request then keeps this price for payRequest and for the order your person pays on Egonex.",
        "properties": {
          "amount": {
            "description": "unit_price × quantity, before shipping and tax",
            "type": "number"
          },
          "currency": {
            "description": "usd",
            "type": "string"
          },
          "delivery_days": {
            "description": "Agreed delivery time in days after payment",
            "type": "integer"
          },
          "expires_at": {
            "description": "Use it in createRequest before this time",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "Pass it as deal_id (works for one request)",
            "type": "string"
          },
          "list_price": {
            "description": "Listed price per unit when it was agreed, USD",
            "type": "number"
          },
          "quantity": {
            "description": "Units the price was agreed for: payRequest takes at most this many",
            "type": "number"
          },
          "unit": {
            "description": "What one unit is",
            "type": "string"
          },
          "unit_price": {
            "description": "Agreed price per unit, USD",
            "type": "number"
          }
        },
        "type": "object"
      },
      "Offer": {
        "properties": {
          "ask_url": {
            "description": "For a person: ask on Egonex",
            "type": "string"
          },
          "availability": {
            "description": "sold_out = can't be ordered until the seller restocks (left out of search; seen only when fetched by id)",
            "enum": [
              "in_stock",
              "sold_out"
            ],
            "type": "string"
          },
          "brand": {
            "description": "Physical items: brand, as the seller gave it (absent when not stated)",
            "type": "string"
          },
          "category": {
            "description": "Category",
            "type": "string"
          },
          "city": {
            "description": "City for in-person listings",
            "type": "string"
          },
          "city_unknown": {
            "description": "true = in person, no city given and it doesn't ship",
            "type": "boolean"
          },
          "condition": {
            "description": "Physical items: new, like_new, good, fair or for_parts (absent when not stated)",
            "type": "string"
          },
          "delivery": {
            "description": "remote, onsite or hybrid",
            "type": "string"
          },
          "delivery_days": {
            "description": "The seller's usual delivery time in days (days to ship for posted items); absent when not stated",
            "type": "integer"
          },
          "description": {
            "description": "Written by the seller",
            "type": "string"
          },
          "digital_delivery": {
            "description": "Digital products: the seller sends a file or a link after payment",
            "enum": [
              "file",
              "link"
            ],
            "type": "string"
          },
          "digital_format": {
            "description": "Digital products: the file type (absent when not stated)",
            "enum": [
              "pdf",
              "video",
              "template",
              "preset",
              "code",
              "other"
            ],
            "type": "string"
          },
          "gtin": {
            "description": "Physical items: barcode (UPC / EAN / ISBN, 8–14 digits, check digit verified) when the seller gave it",
            "type": "string"
          },
          "id": {
            "description": "Listing id",
            "type": "string"
          },
          "kind": {
            "description": "What it is: physical (an item, shipped or picked up), service, or digital (a file or link the seller sends by hand after payment)",
            "enum": [
              "physical",
              "service",
              "digital"
            ],
            "type": "string"
          },
          "matched_words": {
            "description": "Search results only: the words of q this listing matches, as written in q (Chinese, Japanese and Korean text is matched in overlapping two-character pieces, and these are what is listed)",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "missing_words": {
            "description": "Search results only: the words of q this listing doesn't match; absent when it matches them all. A some_words listing without missing_words matched every word, but either it is not delivered the way q asked (online, remote or in person) or some words of q could not be searched",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "model": {
            "description": "Physical items: model name or number, as the seller gave it — match it to compare the exact version",
            "type": "string"
          },
          "order_url": {
            "description": "For a person: order on Egonex",
            "type": "string"
          },
          "photos": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "price": {
            "$ref": "#/components/schemas/Price"
          },
          "relevance": {
            "description": "Search results only: all_words (the listing's own title, description or category name matched every word), some_words, or other_filters (no word matched; another listing in the category or store searched)",
            "type": "string"
          },
          "seller": {
            "$ref": "#/components/schemas/Seller"
          },
          "session_minutes": {
            "description": "Services priced per session or per hour: how long one session is, in minutes",
            "type": "integer"
          },
          "shipping": {
            "description": "Items that ship, when the seller set a shipping fee: charged once per order whatever the quantity, paid at Egonex checkout and by payRequest. Absent when not set (see the store's shipping rules)",
            "properties": {
              "fee": {
                "description": "The shipping fee in USD for the order; absent when free",
                "type": "number"
              },
              "free": {
                "description": "true = free shipping",
                "type": "boolean"
              },
              "international_fee": {
                "description": "Older listings only: the fee to other countries (fee is then the fee inside the seller's country)",
                "type": "number"
              },
              "no_international": {
                "description": "Older listings only: true = it doesn't ship to other countries",
                "type": "boolean"
              }
            },
            "type": "object"
          },
          "ships": {
            "description": "The seller posts it; your person enters the shipping address when paying on Egonex, or you pass it to payRequest when you pay",
            "type": "boolean"
          },
          "stock_left": {
            "description": "Present only when 1 to 3 are left (orders left, for a limited service)",
            "maximum": 3,
            "minimum": 1,
            "type": "integer"
          },
          "title": {
            "description": "Title",
            "type": "string"
          },
          "url": {
            "description": "Listing page",
            "type": "string"
          }
        },
        "type": "object"
      },
      "PayResult": {
        "properties": {
          "next": {
            "description": "What happens next",
            "type": "string"
          },
          "order": {
            "$ref": "#/components/schemas/RequestOrder"
          },
          "paid": {
            "description": "true = the payment went through",
            "type": "boolean"
          },
          "request_id": {
            "description": "Request id",
            "type": "string"
          },
          "status": {
            "description": "Where the order stands, as getRequest reports it: pending (waiting for your user to confirm or decline; nothing has happened yet), declined (your user chose not to go ahead), expired (nobody acted within 7 days; the link no longer works), listing_unavailable (the listing isn't for sale anymore (taken down or sold out), so the request can't go ahead), message_sent (messages only: your user confirmed and the message was sent to the seller), awaiting_order (orders only: your user confirmed and the chat is open, but they haven't placed the order yet), payment_in_progress (orders only: a payment is being processed), payment_failed (orders only: a pay_order payment didn't go through; nothing was charged and the order can still be paid), waiting_for_seller (orders only: the order was sent to the seller, who hasn't accepted yet; nothing has been charged), ready_to_pay (orders only: the order is waiting to be paid (pay_order again, or your user pays on Egonex)), paid (orders only: paid; waiting for the seller to deliver), delivered (orders only: the seller marked it delivered; waiting for your user to confirm receipt), refund_requested (orders only: your user asked for a refund; Egonex is handling it), completed (orders only: the order is complete), refund_pending (orders only: canceled after payment; the refund hasn't gone through yet), refunded (orders only: canceled after payment; your user was refunded), closed_unpaid (orders only: the order closed before anything was charged (close_reason says why))",
            "enum": [
              "pending",
              "declined",
              "expired",
              "listing_unavailable",
              "message_sent",
              "awaiting_order",
              "payment_in_progress",
              "payment_failed",
              "waiting_for_seller",
              "ready_to_pay",
              "paid",
              "delivered",
              "refund_requested",
              "completed",
              "refund_pending",
              "refunded",
              "closed_unpaid"
            ],
            "type": "string"
          }
        },
        "required": [
          "request_id",
          "paid",
          "status",
          "order",
          "next"
        ],
        "type": "object"
      },
      "PaymentOption": {
        "description": "Present on a new order request when it can be paid directly with a Stripe Shared Payment Token.",
        "properties": {
          "amount": {
            "description": "USD per unit",
            "type": "number"
          },
          "currency": {
            "description": "usd",
            "type": "string"
          },
          "max_quantity": {
            "description": "Most units one payment can buy (capped at what's left when only 1 to 3 are left)",
            "type": "integer"
          },
          "next": {
            "description": "How to pay",
            "type": "string"
          },
          "pay_url": {
            "description": "POST here (payRequest)",
            "type": "string"
          },
          "payment_handlers": {
            "description": "UCP payment handlers (com.stripe.payments) with the Stripe network_id",
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "privacy_url": {
            "description": "Egonex Privacy Policy",
            "type": "string"
          },
          "requires_shipping_address": {
            "description": "true = the item ships: the payRequest call that charges needs shipping_address and shipping_address_confirmed=true (a call that only sends the order to the seller doesn't). Absent otherwise",
            "type": "boolean"
          },
          "terms_url": {
            "description": "Egonex Terms of Service",
            "type": "string"
          },
          "unit": {
            "description": "item, package, hour, day, week, month, night, person, project or time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Price": {
        "properties": {
          "amount": {
            "type": "number"
          },
          "currency": {
            "description": "USD",
            "type": "string"
          },
          "text": {
            "description": "Readable price, e.g. $1,150 per item",
            "type": "string"
          },
          "unit": {
            "description": "item, package, hour, day, week, month, night, person, project or time",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Request": {
        "properties": {
          "close_reason": {
            "description": "closed_unpaid only: why the order closed (absent for orders closed before 2026-11-01)",
            "enum": [
              "seller_declined",
              "seller_acceptance_timed_out",
              "seller_canceled_before_payment",
              "buyer_withdrew",
              "payment_deadline_passed"
            ],
            "type": "string"
          },
          "confirm_url": {
            "description": "Give this to your person",
            "type": "string"
          },
          "deal": {
            "$ref": "#/components/schemas/Deal"
          },
          "expires_at": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "Request id",
            "type": "string"
          },
          "kind": {
            "description": "order or message",
            "type": "string"
          },
          "next": {
            "description": "What to do next",
            "type": "string"
          },
          "offer_id": {
            "description": "Listing id",
            "type": "string"
          },
          "order": {
            "$ref": "#/components/schemas/RequestOrder"
          },
          "order_id": {
            "description": "The order this request led to (same as order.id)",
            "type": "string"
          },
          "payment": {
            "$ref": "#/components/schemas/PaymentOption"
          },
          "status": {
            "description": "pending (waiting for your user to confirm or decline; nothing has happened yet), declined (your user chose not to go ahead), expired (nobody acted within 7 days; the link no longer works), listing_unavailable (the listing isn't for sale anymore (taken down or sold out), so the request can't go ahead), message_sent (messages only: your user confirmed and the message was sent to the seller), awaiting_order (orders only: your user confirmed and the chat is open, but they haven't placed the order yet), payment_in_progress (orders only: a payment is being processed), payment_failed (orders only: a pay_order payment didn't go through; nothing was charged and the order can still be paid), waiting_for_seller (orders only: the order was sent to the seller, who hasn't accepted yet; nothing has been charged), ready_to_pay (orders only: the order is waiting to be paid (pay_order again, or your user pays on Egonex)), paid (orders only: paid; waiting for the seller to deliver), delivered (orders only: the seller marked it delivered; waiting for your user to confirm receipt), refund_requested (orders only: your user asked for a refund; Egonex is handling it), completed (orders only: the order is complete), refund_pending (orders only: canceled after payment; the refund hasn't gone through yet), refunded (orders only: canceled after payment; your user was refunded), closed_unpaid (orders only: the order closed before anything was charged (close_reason says why))",
            "enum": [
              "pending",
              "declined",
              "expired",
              "listing_unavailable",
              "message_sent",
              "awaiting_order",
              "payment_in_progress",
              "payment_failed",
              "waiting_for_seller",
              "ready_to_pay",
              "paid",
              "delivered",
              "refund_requested",
              "completed",
              "refund_pending",
              "refunded",
              "closed_unpaid"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "RequestOrder": {
        "description": "The order the request led to: made with payRequest, or placed by your person in the chat after confirming. Times are given only where they matter for the status.",
        "properties": {
          "accept_by": {
            "description": "waiting_for_seller, or paid before the seller accepted: the seller has to accept by then",
            "format": "date-time",
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "auto_confirm_at": {
            "description": "delivered: the order completes on its own then, unless a refund is requested before",
            "format": "date-time",
            "type": "string"
          },
          "currency": {
            "description": "usd",
            "type": "string"
          },
          "deliver_by": {
            "description": "paid: the seller has to deliver by then",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "Order id",
            "type": "string"
          },
          "pay_by": {
            "description": "ready_to_pay: the order closes if nobody pays by then",
            "format": "date-time",
            "type": "string"
          },
          "quantity": {
            "description": "How many units at the listed price (items, hours, nights...); absent when the order doesn't record one, such as an older order or a total the seller quoted",
            "type": "number"
          },
          "refunded_amount": {
            "description": "refunded or completed: what was refunded to your person",
            "type": "number"
          },
          "ship_to": {
            "description": "An order that ships, once it is paid: the area it ships to (the street and name are never returned). payRequest can't change it; your person tells the seller in the Egonex chat",
            "properties": {
              "city": {
                "description": "City",
                "type": "string"
              },
              "country": {
                "description": "2-letter country code",
                "type": "string"
              },
              "postal_code": {
                "description": "US only: the 5-digit ZIP code",
                "type": "string"
              },
              "state": {
                "description": "State or region (US: 2-letter code)",
                "type": "string"
              }
            },
            "required": [
              "city",
              "country"
            ],
            "type": "object"
          },
          "title": {
            "description": "What was ordered: the order's title, as on the order card",
            "type": "string"
          }
        },
        "type": "object"
      },
      "SearchResult": {
        "properties": {
          "next_offset": {
            "type": [
              "integer",
              "null"
            ]
          },
          "note": {
            "description": "How the results were found, when not every word matched or nothing did, or not every word was used",
            "type": "string"
          },
          "offers": {
            "items": {
              "$ref": "#/components/schemas/Offer"
            },
            "type": "array"
          },
          "searched_as": {
            "description": "Only when Egonex searched a rewrite of q (it isn't in English, has words too short to search, ends with a place, or nothing matched): what was searched. matched_words and missing_words are in the words of the search that found the listing: the rewrite, or, for a q that isn't in English, the query as written.",
            "properties": {
              "city": {
                "description": "City read from q and used as the city filter; a short form such as sf comes back as the full name (San Francisco, CA)",
                "type": "string"
              },
              "delivery": {
                "description": "Delivery read from q: listings delivered that way rank first (either-way listings count); it does not filter",
                "enum": [
                  "onsite",
                  "remote"
                ],
                "type": "string"
              },
              "max_price": {
                "description": "Highest price read from q and used as a filter",
                "type": "number"
              },
              "min_price": {
                "description": "Lowest price read from q and used as a filter",
                "type": "number"
              },
              "query": {
                "description": "The English search words that were used",
                "type": "string"
              },
              "reason": {
                "enum": [
                  "translated",
                  "abbreviation",
                  "place",
                  "no_results"
                ],
                "type": "string"
              }
            },
            "type": "object"
          },
          "total": {
            "type": "integer"
          },
          "unused_words": {
            "description": "Words of q that were not used: only the first 12 search words count. Search again with them if they matter.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "Seller": {
        "properties": {
          "answers_questions": {
            "type": "boolean"
          },
          "handle": {
            "description": "Store handle",
            "type": "string"
          },
          "intro": {
            "description": "Written by the seller",
            "type": "string"
          },
          "negative_count": {
            "description": "Counted negative reviews; present with review_count, 0 included",
            "type": "integer"
          },
          "orders_completed": {
            "type": "integer"
          },
          "positive_count": {
            "description": "Counted positive reviews; present with review_count, 0 included",
            "type": "integer"
          },
          "positive_rate": {
            "description": "Percent of counted reviews that are positive, rounded down; present from 10 counted reviews",
            "maximum": 100,
            "minimum": 0,
            "type": "integer"
          },
          "review_count": {
            "description": "Counted buyer reviews; present from 1",
            "type": "integer"
          },
          "trusted": {
            "description": "true = the seller has Egonex's Trusted badge, the same one shown on their public page. Egonex gives it automatically when the seller's recent trading on Egonex reaches the top earn-back step (sellers can't set it), and doesn't show it while their account health is low.",
            "type": "boolean"
          },
          "url": {
            "description": "Store page",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Store": {
        "properties": {
          "offers": {
            "items": {
              "$ref": "#/components/schemas/Offer"
            },
            "type": "array"
          },
          "seller": {
            "$ref": "#/components/schemas/Seller"
          },
          "shop_rules": {
            "description": "The shop's own rules, when the seller wrote them.",
            "properties": {
              "buyer_protection": {
                "description": "Egonex buyer protection, which always applies whatever the shop's rules say",
                "type": "string"
              },
              "lines": {
                "items": {
                  "properties": {
                    "label": {
                      "description": "Shipping, Returns, Hours, Languages…",
                      "type": "string"
                    },
                    "value": {
                      "description": "What the shop says",
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "type": "array"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      }
    }
  },
  "info": {
    "description": "Search what individual people sell on Egonex (secondhand and handmade goods, lessons, local services, creative and professional work, digital goods, tickets), read a store, ask the seller a question and start an order for your person. No API key. Nothing is bought until the person confirms: on the confirm_url page, or by approving a Stripe Shared Payment Token that you pass to payRequest (where direct payment is on). After an order is placed, everything about it (confirming delivery, a refund or a cancellation) is handled on Egonex, not through this API. Browse: https://shop.egonex.ai/sellers",
    "title": "Egonex agent API",
    "version": "1.16.2"
  },
  "openapi": "3.1.0",
  "paths": {
    "/offers": {
      "get": {
        "description": "Natural-language search over listings that are for sale now. Online, either-way and shipped listings are included when a city is given. When you suggest a listing to your person, give them its url (the listing page) so they can open it.",
        "operationId": "searchOffers",
        "parameters": [
          {
            "description": "What the person wants, in a few words (any language). Only the first 12 search words are used (filler words like for, near or cheap don't count, nor do single letters or two-letter words in lowercase: write abbreviations in capitals, such as QA or IT); the rest come back in unused_words. Words are matched whole, with their word forms (lesson / lessons), against listing titles and descriptions; a word naming a category (pets, electronics, fashion, clothing, jewelry, makeup, furniture, toys, baby, camping, hobbies, crafts, books, food, tickets, rentals, templates, video, or the same in Chinese, Japanese or Korean) also matches that category. Rarer words count more, and listings that match only common words are left out. Store names, intros and listing cities are not matched against q: put places in city. q can be in any language. When q isn't English, Egonex also searches an English translation of it; when it has words too short to search, ends with a place (and city is empty) or matches nothing, Egonex searches a rewrite instead. searched_as says what was searched. Online, remote and in person never bring in a listing by themselves: among equally good matches, listings whose title says it come first, then those delivered that way (hybrid counts as both). delivery is an exact filter: remote leaves out hybrid listings.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Category key.",
            "in": "query",
            "name": "category",
            "required": false,
            "schema": {
              "enum": [
                "electronics",
                "fashion",
                "jewelry",
                "beauty",
                "home",
                "toys",
                "baby",
                "sports",
                "hobbies",
                "art",
                "pets",
                "books",
                "food",
                "lessons",
                "local",
                "creative",
                "professional",
                "digital",
                "rentals",
                "other"
              ],
              "type": "string"
            }
          },
          {
            "description": "City for in-person listings, e.g. Austin or Portland, OR. In-person listings in that city come first, then those nearby (same metro area or within about 30 miles); listings done only in person elsewhere are left out. Add the state when several places share the name. Online, either-way and shipped listings are always included; in-person listings without a city are kept and marked city_unknown (unless they ship).",
            "in": "query",
            "name": "city",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Minimum price in USD.",
            "in": "query",
            "name": "min_price",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "description": "Maximum price in USD.",
            "in": "query",
            "name": "max_price",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "description": "remote, onsite or hybrid.",
            "in": "query",
            "name": "delivery",
            "required": false,
            "schema": {
              "enum": [
                "remote",
                "onsite",
                "hybrid"
              ],
              "type": "string"
            }
          },
          {
            "description": "Physical items: the lowest condition accepted (new \u003e like_new \u003e good \u003e fair \u003e for_parts). Listings that don't state one are included.",
            "in": "query",
            "name": "condition",
            "required": false,
            "schema": {
              "enum": [
                "new",
                "like_new",
                "good",
                "fair",
                "for_parts"
              ],
              "type": "string"
            }
          },
          {
            "description": "Only this store (its handle).",
            "in": "query",
            "name": "store",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Results per page (default 10).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Use next_offset from the previous page.",
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResult"
                }
              }
            },
            "description": "Matching listings."
          },
          "400": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          }
        },
        "summary": "Search listings"
      }
    },
    "/offers/{id}/questions": {
      "post": {
        "description": "Answered right away by the seller's Ego when the seller has it on; otherwise answered=false with a reason. Where price talk is on and the seller set a lowest price, Ego can talk price about this listing: it may counter once, and when you agree a price the answer has deal (pass deal.id as deal_id to createRequest within 24 hours). For 24 hours it holds the price it named to you.",
        "operationId": "askSeller",
        "parameters": [
          {
            "description": "Listing id (offers[].id).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "conversation_id": {
                    "description": "From the previous answer, to keep asking about the same listing.",
                    "type": "string"
                  },
                  "question": {
                    "description": "The question, up to 500 characters.",
                    "maxLength": 500,
                    "type": "string"
                  }
                },
                "required": [
                  "question"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Answer"
                }
              }
            },
            "description": "The answer."
          },
          "400": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          },
          "404": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          }
        },
        "summary": "Ask the seller a question about a listing"
      }
    },
    "/requests": {
      "post": {
        "description": "Creates a pending request. Give confirm_url to your person: they confirm (and pay, for an order) on Egonex.",
        "operationId": "createRequest",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "agent_name": {
                    "description": "Your name, shown to the person when they confirm, up to 60 characters.",
                    "maxLength": 60,
                    "type": "string"
                  },
                  "deal_id": {
                    "description": "Optional, kind=order only: deal.id from an askSeller answer in which Ego agreed a price for this listing (within 24 hours, once). The order then uses that price.",
                    "type": "string"
                  },
                  "kind": {
                    "enum": [
                      "order",
                      "message"
                    ],
                    "type": "string"
                  },
                  "message": {
                    "description": "What to tell the seller (quantity, dates, details), up to 1000 characters.",
                    "maxLength": 1000,
                    "type": "string"
                  },
                  "offer_id": {
                    "description": "Listing id.",
                    "type": "string"
                  }
                },
                "required": [
                  "offer_id",
                  "kind"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Request"
                }
              }
            },
            "description": "The pending request."
          },
          "400": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          },
          "404": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          },
          "409": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          }
        },
        "summary": "Start an order or a message for your person"
      }
    },
    "/requests/{id}": {
      "get": {
        "operationId": "getRequest",
        "parameters": [
          {
            "description": "Request id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Request"
                }
              }
            },
            "description": "The request."
          },
          "404": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          }
        },
        "summary": "Check whether the person confirmed"
      }
    },
    "/requests/{id}/pay": {
      "post": {
        "description": "Pays for an order request without the confirm page, when createRequest returned payment. Issue a Stripe Shared Payment Token to payment.payment_handlers[].config.business_profile for at least payment.amount × quantity in USD, approved by your person (plus sales tax where Egonex collects it, from the shipping address for an item that ships and from the card's billing address otherwise: if the token doesn't cover it, nothing is charged and 402 payment_token_unusable gives the total; without a billing address 409 billing_address_required, use confirm_url). Egonex creates the order on a guest account for buyer_email. The result has the same status and order as getRequest (order has its title, quantity, amount and deadlines). The seller confirms an order before the buyer pays: status waiting_for_seller means the order was sent to the seller and nothing was charged; when getRequest shows ready_to_pay, call this again with the same buyer_email and a valid token (or the person pays from the link Egonex emails them); if the seller declines or doesn't respond, nothing is charged. Status paid with order.accept_by means the token was charged first and the seller has until then to accept, otherwise the person is refunded minus the payment processing fee. For an item that ships (payment.requires_shipping_address), the call that charges needs shipping_address and shipping_address_confirmed=true, otherwise nothing is charged (400 shipping_address_required / 400 shipping_address_not_confirmed): ask your person for the address before you pay and read it back to them. A call that only sends the order to the seller charges nothing and doesn't keep an address; pass it on the call that pays. 400 shipping_address_invalid when the address fails the format check (the message names the field) or Stripe can't place it for sales tax; nothing is charged. The address becomes the order's shipping address only once the payment goes through (if it doesn't, nothing is kept and you can retry with a corrected one); order.ship_to then shows the city, state, ZIP code and country (the street and name are never returned). After payment a different address is refused (409 shipping_address_locked): the person tells the seller in the Egonex chat. If the person pays on Egonex instead (confirm_url, or the link in Egonex's email), they enter the address there and no address you passed is used. If the email already has an Egonex account nothing is charged (409 email_has_account): give confirm_url to your person. Calling again after a success returns the same order; nothing is charged twice. If Stripe declines, nothing is charged and getRequest shows payment_failed: retry with a new token and the same buyer_email, or use confirm_url. After 502 payment_error (the payment couldn't be confirmed) it may or may not have gone through: don't call this again while getRequest shows payment_in_progress (Egonex is checking with Stripe, usually a few minutes; 409 payment_in_progress meanwhile, nothing is charged twice). When it no longer does: if it shows paid, nothing more is needed; if it shows payment_failed or ready_to_pay, ask your person for a new approval and call this again with the new token (not the same one). If the listing sold out or there aren't that many left, nothing is charged (409 sold_out / stock_short). 503 payments_unavailable where direct payment is off.",
        "operationId": "payRequest",
        "parameters": [
          {
            "description": "Request id (kind=order).",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "accept_terms": {
                    "description": "true only if your person agreed to Egonex's Terms of Service and Privacy Policy (payment.terms_url, payment.privacy_url).",
                    "type": "boolean"
                  },
                  "buyer_email": {
                    "description": "Your person's email: receipts, the order and seller replies go there.",
                    "type": "string"
                  },
                  "buyer_name": {
                    "description": "Optional name shown to the seller (up to 40 characters).",
                    "type": "string"
                  },
                  "delivery_days": {
                    "description": "Days the seller has to deliver once the order starts (it starts when it is paid and accepted): shipping time for an item, the day of the lesson or service, the start of a rental, 1 for digital goods (default: the listing's delivery_days when it has one, else 3).",
                    "maximum": 60,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "quantity": {
                    "description": "Units at the listed price (default 1).",
                    "maximum": 99,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "shared_payment_token": {
                    "description": "Stripe Shared Payment Token (spt_...) your person approved.",
                    "type": "string"
                  },
                  "shipping_address": {
                    "description": "For an item that ships (payment.requires_shipping_address): where to ship it, as your person confirmed it. Required on the call that charges (when the seller accepts first, the call after they accept); a call that only sends the order doesn't keep it, and after payment it can't be changed. US addresses: 2-letter state code and a 5-digit ZIP code or ZIP+4.",
                    "properties": {
                      "city": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "country": {
                        "description": "2-letter country code (ISO 3166-1)",
                        "maxLength": 2,
                        "minLength": 2,
                        "type": "string"
                      },
                      "line1": {
                        "description": "Street address",
                        "maxLength": 200,
                        "type": "string"
                      },
                      "line2": {
                        "description": "Apartment, suite or unit (optional)",
                        "maxLength": 200,
                        "type": "string"
                      },
                      "name": {
                        "description": "Recipient's full name",
                        "maxLength": 100,
                        "type": "string"
                      },
                      "postal_code": {
                        "description": "ZIP or postal code; for the US 12345 or 12345-6789",
                        "maxLength": 20,
                        "type": "string"
                      },
                      "state": {
                        "description": "State or region; for the US the 2-letter USPS code",
                        "maxLength": 100,
                        "type": "string"
                      }
                    },
                    "required": [
                      "name",
                      "line1",
                      "city",
                      "country"
                    ],
                    "type": "object"
                  },
                  "shipping_address_confirmed": {
                    "description": "true only if you read shipping_address back to your person and they said it's right. Required with shipping_address on the call that charges.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "shared_payment_token",
                  "buyer_email",
                  "accept_terms"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayResult"
                }
              }
            },
            "description": "Where the order stands (the same status and order as getRequest)."
          },
          "400": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          },
          "402": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          },
          "404": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          },
          "409": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          },
          "503": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          }
        },
        "summary": "Pay for an order with a Stripe Shared Payment Token"
      }
    },
    "/stores/{handle}": {
      "get": {
        "operationId": "getStore",
        "parameters": [
          {
            "description": "Store handle, the part after /@ in the store URL.",
            "in": "path",
            "name": "handle",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Store"
                }
              }
            },
            "description": "The store."
          },
          "404": {
            "description": "Error: {\"error\": {\"code\": \"...\", \"message\": \"...\"}}"
          }
        },
        "summary": "Read a store and everything it sells"
      }
    }
  },
  "servers": [
    {
      "url": "https://api.egonex.ai/api/v1/agent"
    }
  ]
}