Create order

POST /api/v1/orders tenant key

Fulfillment, step 2. Commits a PENDING_PAYMENT order (from POST /shipping-quote) to one of its quoted rate_ids: the order moves to PENDING and is queued for pick-pack, and you are billed exactly what that rate quoted. This call purchases the shipping label synchronously — it contacts the carrier, so budget several seconds and set your client timeout accordingly. Retrying is always safe: every failure mode leaves the order in PENDING_PAYMENT with nothing committed, label purchase is idempotent (a retry never buys a second label), and card preparation is all-or-nothing. Returns 201.

Try it POST /api/v1/orders money

These inputs are shared across all docs pages, so an id entered here carries over.

request body
object · 2 keys
{
  "order_id": 0,
  "rate_id": ""
}
response

Not run yet. Press Run to make a live call against https://service.rip.fun (through this demo's server-side proxy; the API key never reaches the browser).

curl (tracks the inputs above)
curl -X POST 'https://service.rip.fun/api/v1/orders' \
  -H 'X-API-Key: rip_…' \
  -H 'Content-Type: application/json' \
  -d '{"order_id":0,"rate_id":""}'

Request fields

FieldTypeRequiredDescription
order_idnumberyesThe PENDING_PAYMENT order id from /shipping-quote
rate_idstringyesA rate_id from that order's quoted rates[]

Response fields (data)

FieldDescription
order_id / statusThe committed order + its new status ("PENDING")
unique_ids / ship_by_atCards on the order + target ship date
shippo_rate_id / shippo_address_id / shippo_shipment_idThe committed (quoted) rate + shipment objects
shippo_tracking_number / shippo_tracking_url / shippo_label_url / label_purchased_atLabel + tracking, populated once purchased
previous_tracking_numbersstring[] — tracking numbers of labels this order was moved off, oldest first; empty unless we re-labelled it. Those labels will never move — see order.tracking_updated in the events feed
tracking_status / tracking_status_atLatest carrier status of the current label (PRE_TRANSIT | TRANSIT | DELIVERED | RETURNED | FAILURE) and when the carrier recorded it; null until first checked (every 2 hours)

Errors

StatusCodeWhen
400invalid inputorder_id or rate_id missing/invalid
404order not foundorder not part of your account
409already submittedorder is not PENDING_PAYMENT (already committed) — carries data: {order_id, status, unique_ids}
422SHIPPO_REJECTEDShippo refused to sell a label for this shipment (address, parcel or service problem). messages[] carries Shippo’s reasons and retryable is false — fix the input and re-quote; retrying the same order_id will fail the same way
422RATE_UNAVAILABLEthe quoted rate was rejected and a fresh quote returned no rates for this destination. retryable: false — re-quote with a different address or parcel
502SHIPPO_ERRORShippo timed out or returned 5xx. retryable: true — back off and retry the same order_id + rate_id; the order stays PENDING_PAYMENT
502SHIPPO_PURCHASE_AMBIGUOUSthe quoted rate validated live but the purchase call threw, so a charge may have gone through. Do not switch rates; retry the same order_id + rate_id or contact support
409LABEL_FAILED_REPEATEDLYfive consecutive label failures on this order. No further Shippo call is made; the response carries the last reason. Re-quote via POST /shipping-quote to start over
400card not preparablea card’s status changed after you quoted — the order is untouched; re-quote (or poll GET /cards) if the card is no longer available

See Errors for the response envelope and the full code list.

Flow

  1. Needs order_id + a rate_id from POST /api/v1/shipping-quote. See the Shipping quote flow.