API docs

Guide: marketplace orders (Etsy, Amazon, eBay)

A shop sells on Etsy, Amazon or eBay, through Flxpoint or its own integration. When an order comes in, it needs to land on the POS so that:

  • the stock comes off the shelf (and off the right lot),
  • staff see it at the register,
  • and the shop's reports include it.

This guide walks through that with POST /v1/orders.

Permissions: orders: write, plus products: read to look up SKUs.

1. A paid order: completes on the spot

curl -X POST https://app.blackbeachpos.com/api/v1/orders \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{
    "external_reference": "ETSY-3318842210",
    "channel": "Etsy",
    "location_id": 18,
    "lines": [
      { "sku": "CDL-SSD-08", "qty": 2, "unit_price_cents": 2400 },
      { "sku": "SOAP-LAV", "qty": 3, "unit_price_cents": 800 }
    ],
    "customer": { "email": "buyer@example.com", "first_name": "Casey", "last_name": "Morgan" },
    "shipping_cents": 695,
    "shipping_address": { "name": "Casey Morgan", "line1": "12 Elm St", "city": "Dayton", "state": "OH", "postal_code": "45402", "country": "US" },
    "tax_exempt": true,
    "payment_reference": "ETSY-PAY-771"
  }'

What each part does:

  • external_reference is the marketplace's order number, up to 36 characters. If your job retries, or the same order is sent twice, Black Beach POS returns the existing order with 200 and creates nothing new. Always send it.
  • unit_price_cents is the price the buyer paid on the marketplace. Leave it out to use the POS price.
  • tax_exempt: true: Etsy, Amazon and eBay are marketplace facilitators in most US states and collect and remit sales tax themselves. Sending this stops the shop from charging tax a second time. For channels where the shop owes the tax (its own website, for example), leave it out; Black Beach POS then taxes at the location's rate and the total includes it.
  • customer is matched by email, or created if new. You don't need customers: write for this.
  • Lots. SOAP-LAV tracks lots, so the soap comes off the earliest-expiring lot with enough stock, the same as at the register. To ship from a particular lot, send its lot_id (from GET /v1/inventory/lots). The order line reports lot_id and lot_number either way.
  • Payment. The order is recorded as paid with an external payment for the full total, referenced ETSY-PAY-771, and completes immediately. Stock comes off location 18, and inventory.changed, order.created and sale.completed fire.

Response (abridged):

{ "status": "ok", "data": { "object": "order", "id": 5530, "number": "S18-000041", "status": "completed", "source": "api", "total_cents": 7895, "tax_cents": 0, "lines": [ { "sku": "CDL-SSD-08", "qty": 2, "lot_id": null, "lot_number": null, "...": "…" }, { "sku": "SOAP-LAV", "qty": 3, "lot_id": 62, "lot_number": "LAV-2510-A", "...": "…" } ], "payments": [ { "tender": "external", "amount_cents": 7895, "reference": "ETSY-PAY-771" } ], "next_action": null } }

2. A serialized item: held for the register

Serialized items (a numbered art print, an electric diffuser with a warranty serial) are sold unit by unit, and the unit is picked by the staff member who packs it. So an order with any serialized line is saved held:

curl -X POST https://app.blackbeachpos.com/api/v1/orders \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{
    "external_reference": "AMZ-113-5550123-7781",
    "channel": "Amazon",
    "lines": [ { "sku": "DIF-ELEC-01", "qty": 1, "unit_price_cents": 8900, "serial_number": "WE-DIF-00417" } ],
    "customer": { "email": "buyer2@example.com", "first_name": "Alex", "last_name": "Kim" },
    "fulfillment": "ship",
    "shipping_address": { "name": "Alex Kim", "line1": "400 Main St", "city": "Akron", "state": "OH", "postal_code": "44308", "country": "US" },
    "tax_exempt": true,
    "payment_reference": "AMZ-PAY-780"
  }'
{ "status": "ok", "data": { "object": "order", "id": 5531, "status": "held", "next_action": "complete_at_register", "...": "…" } }

Staff see the order in the register's held tickets. The note tells them it's already paid through Amazon, so they take payment as External. They pick the unit (your serial_number is shown to them as the requested one) and complete the sale. Then you get sale.completed and inventory.changed.

An order sent with paid: false is held the same way, with next_action: "collect_payment_at_register".

3. Cancellations

POST /v1/orders/{id}/void with a reason. Stock returns to the shelf, to the same lots. An order that's been partly refunded can't be voided (409 SALE_REFUNDED); process a return in Black Beach POS instead.

4. Tracking what happened

  • Subscribe the endpoint to order.created, sale.completed, sale.voided and sale.refunded.
  • GET /v1/orders?source=api&updated_since=… lists every API order and its current state.
  • GET /v1/orders?external_reference=AMZ-113-5550123-7781 finds one order by your reference.