Cancel an order and refund all successful charges. The order is cancelled in the production system first, then all charges are refunded. refund_status says what happened to the money: refunded, not_owed, or pending when the refund failed at the card processor and is being retried; the order is cancelled either way. An order held for a person's approval (pending_approval) was never charged or sent: it is cancelled on our record alone, refund_status: not_owed, and its approval link stops deciding; while an approval is placing it, the cancel is 409 concurrent_modification.
- Credential
- An API key in
x-api-key - Scopes
orders:write
Parameters
idpath · stringrequiredThe order's
order_id, or itsportal_order_id(ord_…): either resolves the same order. An id the order answered to before it was re-routed resolves too.Idempotency-Keyheader · string (uuid)Unique key for idempotent requests. If you retry a request with the same key within 24 hours, you receive the original response. The key is bound to the request payload: reusing it for a different payload returns 422
idempotency_key_reuserather than the original response, so a changed request is never silently dropped. The binding is over the JSON's content, not its bytes — keys in another order or other whitespace are the same request. Generate a new key for each new request. On an operation that moves money (an order, a batch, an item, a shipping or address change, a cancellation's refund), a key that cannot be checked because the idempotency ledger is unreachable is answered 503idempotency_unavailablewithRetry-After, and nothing runs or is charged: retry with the same key.
Request
DELETE /api/v1/order/{id}/cancel
curl -X DELETE "https://portal.printedsimply.com/api/v1/order/test_ord_wVK9ZiG-VYiPrlSeBUBmrUVk/cancel" \
-H "x-api-key: ps_test_YOUR_KEY" \
-H "Idempotency-Key: cancel-order-$(date +%s)"Response 200
Order cancelled and refunded
data
order_idstringrequiredtest_modebooleanTrue when the cancelled order was a sandbox order.
refundedstringrequiredAmount refunded (e.g. '$12.50')
refunded_centsintegerrequiredrefund_statusstringWhat happened to the money.
refunded: everything the order's charges still held went back (refunded_centsequalsowed_cents).not_owed: nothing was charged or it was already refunded, as for every sandbox order.pending: the order is cancelled but some or all of the refund failed at the card processor; it is retried automatically,refunded_centsis what went back now andowed_centswhat is due in total.One of
refundednot_owedpendingowed_centsintegerWhat the order's charges held when it was cancelled: the amount the cancellation refunds.
meta
pageintegertotalintegerlimitintegerThe page size actually applied, which is not necessarily the one asked for — the operation's own ceiling wins.
pagesintegertotaloverlimit, rounded up.next_cursorstring | nullOn a cursor-paged operation: send this back as
cursorfor the next page. Null on the last page. Absent on operations that do not page by cursor.has_morebooleanOn a list operation whose
metaisListMeta: whether another page follows this one.
{
"status": "success",
"data": {
"order_id": "test_ord_JyZLq7sUxTZxc7qjzI76ZQYU",
"refunded": "$0.00",
"refunded_cents": 0,
"refund_status": "not_owed",
"owed_cents": 0,
"test_mode": true
},
"request_id": "4e3753e1-48dd-4313-bfd8-48e4af4e116a"
}Errors
already_cancelled — the order was cancelled before; nothing more is refunded or sent. Read it with GET /order/{id}.
Missing, invalid or expired API key:
missing_api_key(none sent),invalid_api_key(unknown or revoked),key_expired(past the expiry set when it was created; create a new key).404Resource not found
not_cancellable — the order has gone into production (or shipped, been delivered, been flagged or is being re-routed): an order can be cancelled only before production, while it is pending_payment, paid or accepted. Not a retry: the window does not reopen. An order already cancelled answers 400 already_cancelled instead. production_reconciliation_required — this order has an unresolved production submission. Nothing is cancelled or refunded until support reconciles the actual plant order.
Rate limit exceeded. Two windows can produce this status and
error.codesays which:rate_limit_exceededfor the per-minute sliding window,daily_quota_exceededfor the plan's daily quota. Both carryRetry-After; the daily one also carriesX-Daily-LimitandX-Daily-Remaining. The per-minute limits are plan-based — see Rate Limits above, or call GET /v1/me for this credential's own figures.502Production system error
idempotency_unavailable — the request carried an
Idempotency-Keyand the ledger that makes it mean at-most-once could not be reached, so nothing ran and nothing was charged; retry the same request with the same key afterRetry-After.