API reference · Orders
Withdraw an add-on offer (not yet available)
/orders/{orderId}/addition-offers/{offerRef}/withdrawNot yet available. Order additions are switched off in production and in the sandbox, so no buyer can ask for added cards and no offer can be sent: the lists answer eligibility.eligible: false with the reason feature_disabled, and sendOrderAdditionOffer answers 422 ORDER_ADDITION_NOT_ELIGIBLE. Do not build against this operation yet; the changelog announces when additions open. The example request shows the shape only and cannot succeed in the sandbox: sending an offer answers 422 ORDER_ADDITION_NOT_ELIGIBLE, and declining a request or withdrawing an offer answers 404 because none can exist. Take back an offer the buyer has not started paying for, with an optional note. Its reserved units are released at once and Snapcaster sends order.addition_offer.updated with reason: withdrawn. An offer the buyer is paying for cannot be withdrawn until its payment resolves. Returns the withdrawn offer.
Example
These examples send requests to the sandbox.
Replace the example orderId and offerRef in the URL with your own.
curl --request POST \
--url 'https://api-sandbox.snapcaster.ca/api/v1/marketplace/orders/ord_sandbox_01K4A8Y6D4QJH2N3P5R7S9T0VW/addition-offers/oao_9e2b7c4d1a6f43b8a5c0d3e7f1b8a264/withdraw' \
--header "Authorization: Bearer $MARKETPLACE_API_KEY" \
--header "Idempotency-Key: $(uuidgen)" \
--header 'Content-Type: application/json' \
--data '{}'$(uuidgen) makes a new Idempotency-Key each time you run the command. To retry a command after a lost response, send the key from the first attempt.
{
"success": true,
"data": {
"offer_ref": "oao_9e2b7c4d1a6f43b8a5c0d3e7f1b8a264",
"status": "withdrawn",
"lines": [
{
"sku_id": 14602,
"product_id": 86,
"quantity": 2,
"reference_unit_price_cents": 450,
"unit_price_cents": 400,
"name": "Abyssal Nightstalker",
"set_name": "Portal Second Age",
"condition": "Near Mint",
"category_name": "Magic: The Gathering",
"language": "English",
"finish": "Normal",
"collector_number": null,
"rarity": "Uncommon"
}
],
"money": {
"currency": "CAD",
"merchandise_cents": 800,
"reference_merchandise_cents": 900,
"shipping_cents": 0,
"purchase_fee_cents": 28,
"tax_cents": 104,
"total_cents": 932,
"tax_lines": [
{
"label": "HST",
"rate": 0.13,
"amount": 104
}
]
},
"shipping_upgrade": null,
"note": "Two more, at the price you paid",
"request_ref": "oar_5c1e9a7f3b2d48e6a0f4c8d1b7e3a925",
"support_case_id": null,
"replaces_offer_ref": null,
"sent_at": "2026-09-04T19:14:03.000Z",
"expires_at": "2026-09-05T19:14:03.000Z",
"resolved_by_party": "seller",
"resolved_at": "2026-09-04T19:40:12.000Z",
"resolution_note": "Found a better copy, sending a new offer",
"payment": null,
"seller_fees": {
"commission_cents": 40,
"processing_fee_cents": 57,
"platform_collected_tax_cents": 0,
"fee_terms": {
"marketplace_fee_rate_basis_points": 500,
"marketplace_fee_per_item_cap_cents": 2500,
"purchase_fee_rate_basis_points": 350,
"processing_fee_rate_basis_points": 290,
"processing_fee_fixed_cents": 30
}
}
}
}Endpoint
| Environment | URL |
|---|---|
| Sandbox | https://api-sandbox.snapcaster.ca/api/v1/marketplace |
| Production | https://api.snapcaster.ca/api/v1/marketplace |
marketplaceApiKey-http bearer. Send the seller's marketplace API key asAuthorization: Bearer mp_{sellerCode}_{hex}. Themp_{sellerCode}_prefix identifies the seller; the trailing hex is the secret. The seller generates the key and supplies it to your platform.
Request
Path parameters
orderIdstring requiredThe opaque public order id (the webhook/poll
order_id).Constraints: minimum length: 1 Example
ord_sandbox_01K4A8Y6D4QJH2N3P5R7S9T0VWofferRefstring requiredThe add-on offer id (
oao_…) from the send, the list or a webhook.Constraints: pattern:
^oao_[0-9a-f]{32}$Exampleoao_9e2b7c4d1a6f43b8a5c0d3e7f1b8a264
Headers
Idempotency-Keystring requiredKeep this UUID when retrying the same order operation and body. Keys remain valid for the lifetime of the order. Changed contents return 409 IDEMPOTENCY_CONFLICT; a concurrent attempt returns 409 REQUEST_IN_PROGRESS with Retry-After.
Constraints: format: uuid Example
f04e4a96-3c99-44dc-abce-5b6862c589c9X-Snapcaster-Api-VersionstringOverride the platform pin for this request only. Webhook versions and the platform pin do not change.
Constraints: allowed values:
2026-10Example2026-10
Request body
Request body (application/json): End
notestringA short reason the other party reads beside the ending.
Constraints: minimum length: 1; maximum length: 1000
Response
200
The offer, now withdrawn.
Response body: Store
successboolean requiredWhether the operation completed as requested.
Constraints: allowed values:
trueExampletruedataStorerequiredOrder Addition Offer The operation or event payload.
Show child fieldsHide child fields
data.string requiredoffer_ref The opaque public offer id (
oao_…) - the{offerRef}of the withdraw and decline paths.Example
oao_9e2b7c4d1a6f43b8a5c0d3e7f1b8a264data.string requiredstatus sentandacceptedare the two OUTSTANDING states:acceptedmeans the buyer approved the exact amount and a payment is in flight, which is why the offer can no longer be withdrawn, replaced or expired.withdrawnis the seller taking it back;declinedis the buyer’s answer;expiredis the 24 hours running out;replacedis a different offer sent in its place;paidmeans the payment succeeded and the cards are now purchases on the order;payment_blockedmeans a captured payment was screened out and returned. Every ending is one-way, and every one butpaidfrees the stock the offer held -paidconverts it into the purchase.Constraints: allowed values:
sent,accepted,withdrawn,declined,expired,replaced,paid,payment_blockedExamplewithdrawndata.lines OrderrequiredAddition Offer Line[] The line items in this request, response, or event.
Show child fieldsHide child fields
data.integer requiredlines[]. sku_id The exact printing offered. Everything beside it is frozen from it.
Example
14602data.integer requiredlines[]. product_id See Canonical catalog in Core concepts.
Example
86data.integer requiredlines[]. quantity The number of units.
Example
2data.integer requiredlines[]. reference_unit_price_cents The seller’s live listing price when the offer was authored: the ceiling this offer was allowed to charge up to, and the “was” price a discount reads against.
Example
450data.integer requiredlines[]. unit_price_cents What this offer charges per unit; at or below the reference.
Example
400data.string or null requiredlines[]. name Example
Abyssal Nightstalkerdata.string or null requiredlines[]. set_name Example
Portal Second Agedata.string or null requiredlines[]. condition The normalized condition assigned to the card.
Example
Near Mintdata.string or null requiredlines[]. category_name Example
Magic: The Gatheringdata.string or null requiredlines[]. language The language of the card printing.
Example
Englishdata.string or null requiredlines[]. finish The catalog’s printing, under the name the order line snapshot uses.
Example
Normaldata.string or null requiredlines[]. collector_number Example
nulldata.string or null requiredlines[]. rarity The rarity assigned to the card printing.
Example
Uncommon
data.money OrderrequiredAddition Offer Money Show child fieldsHide child fields
data.string requiredmoney. currency The ISO 4217 currency code used for monetary amounts.
Example
CADdata.integer requiredmoney. merchandise_cents The offered cards, AFTER any seller discount.
Example
800data.integer requiredmoney. reference_merchandise_cents The same cards at the seller’s listing prices; above
merchandise_centsby the discount.Example
900data.integer requiredmoney. shipping_cents The shipping DIFFERENCE over shipping already paid for this parcel. EXACTLY 0 when the combined remaining quantities still fit the shipping option already paid for - nothing extra is charged for carriage the buyer has. Otherwise it is the
shipping_upgradeoption’s price less every shipping amount this parcel has already collected, including earlier paid upgrades, so a second upgrade never re-charges the first.Example
0data.integer requiredmoney. purchase_fee_cents The buyer purchase fee at the ORIGINAL order’s frozen rate, on the discounted merchandise.
Example
28data.integer requiredmoney. tax_cents Example
104data.integer requiredmoney. total_cents The EXACT amount the buyer would pay - the sum of the four components above, frozen for the offer’s whole validity period. Nothing may accept for a different figure.
Example
932data.array of object requiredmoney. tax_lines Show child fieldsHide child fields
data.string requiredmoney. tax_lines[]. label Example
HSTdata.number requiredmoney. tax_lines[]. rate The decimal tax rate applied to the taxable amount.
Example
0.13data.integer requiredmoney. tax_lines[]. amount The monetary amount in minor currency units.
Example
104
data.shipping_upgrade Orderor null requiredAddition Offer Shipping Upgrade The shipping option this addition would UPGRADE the parcel to, or null when it rides the one already paid for. All purchased additions share the original parcel: there is never a second shipment. The upgrade becomes the order’s effective option and tracking requirement only when the payment succeeds, and the historical shipping charges are not rewritten - each stays on the payment that collected it. The amount is
money.shipping_cents.Show child fieldsHide child fields
data.string requiredshipping_upgrade. method The upgraded option’s label, in the wording an order’s shipping method uses.
data.boolean requiredshipping_upgrade. is_tracked Whether the upgraded option requires tracking when the order is marked shipped.
data.string or null requirednote The seller’s own words beside the quote; null when none was given.
Example
Two more, at the price you paiddata.string or null requiredrequest_ref The buyer request this offer answered, or null when the seller offered directly.
Example
oar_5c1e9a7f3b2d48e6a0f4c8d1b7e3a925data.integer or null requiredsupport_case_id Example
nulldata.string or null requiredreplaces_offer_ref The offer this one replaced, or null when it replaced none.
Example
nulldata.string requiredsent_at Example
2026-09-04T19:14:03.000Zdata.string requiredexpires_at When the offer and its stock hold stop being valid: 24 hours after
sent_at. Show it.Example
2026-09-05T19:14:03.000Zdata.string or null requiredresolved_by_party Who ended it -
buyeron a decline,selleron a withdrawal or replacement,systemon expiry, which belongs to nobody. Null while outstanding.Constraints: allowed values:
buyer,seller,operator,system,nullExamplesellerdata.string or null requiredresolved_at Example
2026-09-04T19:40:12.000Zdata.string or null requiredresolution_note Example
Found a better copy, sending a new offerdata.payment Orderor null requiredAddition Payment The buyer’s payment for this offer, or null until one accepts it.
Show child fieldsHide child fields
data.string requiredpayment. payment_ref The opaque public payment id (
oap_…).data.string requiredpayment. status processingmeans the answer is not in yet - a browser redirect does not prove a payment succeeded, so keep asking.succeededmeans the cards are on the order.failedmeans the attempt collected nothing and the offer can be accepted again.blockedmeans a captured payment was screened out and returned; this offer is over.Constraints: allowed values:
processing,succeeded,failed,blockeddata.string requiredpayment. currency The ISO 4217 currency code used for monetary amounts.
data.integer requiredpayment. amount_cents The exact amount the buyer approved, frozen from the offer.
data.string requiredpayment. accepted_at data.string requiredpayment. completes_at When this attempt’s 15-minute completion window closes - distinct from the offer’s own 24 hours. Past it a
processingpayment is UNKNOWN rather than failed, and is reconciled against the provider.data.string or null requiredpayment. resolved_at data.string or null requiredpayment. failure_reason data.integer requiredpayment. attempts Above 1 when a declined card was retried on the same payment.
data.seller_fees OrderrequiredAddition Offer Seller Fees Show child fieldsHide child fields
data.integer requiredseller_fees. commission_cents Commission on the discounted merchandise, capped per UNIT at the order’s frozen cap.
Example
40data.integer requiredseller_fees. processing_fee_cents Processing on the WHOLE additional payment - purchase fee and tax included - plus one fixed component for this one payment. It is never reapplied to the original capture.
Example
57data.integer requiredseller_fees. platform_collected_tax_cents Example
0data.object requiredseller_fees. fee_terms The five terms this quote was priced at: the ORDER’s frozen terms as captured, never today’s Marketplace settings. An order that cannot prove all five cannot carry an addition at all.
Show child fieldsHide child fields
data.integer requiredseller_fees. fee_terms. marketplace_fee_rate_basis_points Example
500data.integer requiredseller_fees. fee_terms. marketplace_fee_per_item_cap_cents Example
2500data.integer requiredseller_fees. fee_terms. purchase_fee_rate_basis_points Example
350data.integer requiredseller_fees. fee_terms. processing_fee_rate_basis_points Example
290data.integer requiredseller_fees. fee_terms. processing_fee_fixed_cents Example
30
Errors
Errors return a Marketplace body, except HTTP 413, 500 (Api). Error codes explains both error bodies and lists every code.
400
INVALID_REQUESTIDEMPOTENCY_KEY_REQUIREDUNSUPPORTED_API_VERSIONInvalid command body or missing/invalid UUID Idempotency-Key. Unknown or retired API-version override (
UNSUPPORTED_API_VERSION).Do this: Correct the request fields and supply a UUID Idempotency-Key. Keep the same key when retrying the same command. For UNSUPPORTED_API_VERSION, choose a supported version from the API versioning guide.
401
UNAUTHORIZEDMissing or invalid marketplace API key (
UNAUTHORIZED).Do this: Send the marketplace API key for this seller as a Bearer token, then retry.
403
SUBSCRIPTION_EXCLUDES_ORDERSThe platform's subscription is
inventory, which does not include orders (SUBSCRIPTION_EXCLUDES_ORDERS). Onlyordersandbothsubscriptions read and act on orders.Do this: Do not retry. Ask Snapcaster to change the platform subscription to
ordersorbothif the platform should handle orders.404
ORDER_NOT_FOUNDORDER_ADDITION_OFFER_NOT_FOUNDOrder additions are not yet available. No order matches this id for the authenticated seller (
ORDER_NOT_FOUND), or no add-on offer with this id is on the order (ORDER_ADDITION_OFFER_NOT_FOUND). Another seller's order also returns 404.Do this: Read GET /orders/{orderId}/addition-offers for the offer ids on the order.
409
IDEMPOTENCY_CONFLICTREQUEST_IN_PROGRESSORDER_ADDITION_OFFER_NOT_SENTOrder additions are not yet available. IDEMPOTENCY_CONFLICT or REQUEST_IN_PROGRESS. Retry an in-progress command with the same key after Retry-After seconds.
ORDER_ADDITION_OFFER_NOT_SENT: the offer already ended, or the buyer is paying for it;details.statussays which.Do this: For REQUEST_IN_PROGRESS, wait Retry-After seconds and retry the same key and body. For IDEMPOTENCY_CONFLICT, reuse the original body or create a new UUID for a different operation. For ORDER_ADDITION_OFFER_NOT_SENT, read GET /orders/{orderId}/addition-offers for the offer's current status.
413
PAYLOAD_TOO_LARGEThe body is larger than this route accepts (
PAYLOAD_TOO_LARGE).Do this: Send a smaller body and retry.
500
INTERNAL_ERRORAn unexpected failure (
INTERNAL_ERROR).Do this: Retry with bounded retries and jitter. If the failure persists, contact Snapcaster with the X-Correlation-ID response header.