Freeport Seller API

Orders and chat

An order is paid before you ever see it: the payment provider holds the buyer's payment, you accept within thirty minutes, deliver within twice your promised time (never less than an hour), and the buyer confirms (or three days pass). Freeport then authorises release of the seller's proceeds into a pending balance. Your software's job is the middle: hear about it, accept it, deliver it, and talk to the buyer if needed.

Hearing about it

Three ways, from best to worst:

  • Webhooks. Subscribe to order.paid and the rest; the body carries the order exactly as GET /v1/orders/{id} returns it. See Webhooks.
  • The change token. GET /v1/orders/changes answers with an ETag. Poll it with If-None-Match every few seconds: a 304 costs nothing on either side, a 200 means something moved and it is time to read the feed. Never poll the feed itself in a loop.
  • The feed. GET /v1/orders?state=paid pages your book newest first; ?updated_since= walks everything that changed after a moment, oldest first, for a catch-up after downtime. The moment is RFC 3339, with seconds and either Z or an offset written with its colon (2026-10-06T12:00:00Z); +0100 and a time without seconds are refused.

What an order carries

An order says what was sold as it read when it was bought: the title, the unit, the description and the facts come from the order, and editing the listing afterwards changes none of them, nor the delivery deadline, which is worked out from the delivery time the buyer was promised.

Everything a deliverer needs and nothing they do not: the listing and your external id for it, the quantity, the realm with its region and faction, the buyer's character name, or on a top-up their player id (buyer.player_id) and, where the delivery method takes one, the zone or server number that goes with it (buyer.zone_id), the money split (subtotal, your fee, your net), the deadlines, the state and the sequence number of the last event (last_event_seq). Sequence numbers run in one series across the whole platform, so the gaps between one order's events are normal; only their order carries meaning. For an account order the buyer's credentials go through POST /v1/orders/{id}/credentials, encrypted, never through chat.

The three moves

  • POST /v1/orders/{id}/accept: you have seen it and will deliver. The delivery clock starts.
  • POST /v1/orders/{id}/deliver: the goods are with the buyer. Their confirm clock starts. On an account order the credentials must be stored first.
  • POST /v1/orders/{id}/decline: you cannot fill it. The buyer is refunded in full and your stock is restored. Say why with an optional reason: no_stock, price_mistake, cannot_deliver, buyer_asked or other. no_stock also takes the listing off sale until you put it back. A decline is counted in your reliability figures, and is still better than an expiry: orders left to run out are what pause your listings.

Every move answers with the order after it. A move the state machine forbids is a 409 with illegal_transition; the order's current state is in the body, so a tool that raced a buyer's cancel learns what happened in one round trip.

Chat

GET /v1/orders/{id}/messages is the thread, oldest first; POST adds your words. The buyer's and the system's messages arrive as order.message events, never your own. Chat is read by staff during a dispute, and is scanned for attempts to move a trade off the platform, so keep it to the delivery.

Disputes and refunds

A buyer who did not receive what they paid for opens a dispute; you receive order.disputed with the case and the time you have to answer it, then order.dispute_resolved with the outcome. Which event comes with it depends on where the payment went. Back to the buyer in full (outcome: "buyer"): order.refunded, and the stock is restored. To you (outcome: "seller"): order.completed. Divided between you (outcome: "split"): neither. The order becomes partially_refunded, and a tool that follows the money by order.refunded and order.completed alone never hears of a split. Whichever way it ends, the system's line in the chat saying so arrives as order.message. Your software can do more than know: it can put your side on the record, refund in full, and agree a settlement with the buyer, all covered in Disputes. A farm with a dispute rate is a farm that is about to be asked about it, and one that answers inside the window is asked less.