TCG Plein API Docs
Beta The seller API is still in beta, so small changes can happen while it settles. Questions or suggestions? Let us know on the support page.
Selling

Orders

Reading orders needs orders:read; generating a label and marking an order shipped need orders:write.

The slice model

A buyer's checkout can contain listings from several sellers at once, and several listings from you in the same checkout. Every individual listing sold becomes its own order row (one row per item, per seller). The rows that share a slice_key are exactly the rows from one checkout that belong to you: they were created together, and they ship together. GET /orders lists individual rows; GET /orders/{id}, the label endpoint and the ship endpoint all operate on the whole slice that the given row id belongs to, not just that one row.

List orders

GET /orders

Query parameters

Parameter Type Required Description
status string Optional pending, shipped, received, cancelled or disputed; see Values.
since string Optional ISO date/datetime. Only orders created at or after this point.
page / per_page integer Optional See Pagination.

Each row includes the sold item, tracking, and your financial breakdown for that row (seller_net, seller_fee, commission, refunded_amount). Those figures describe the article only. The buyer's shipping fee is never part of a row: it is reported once per slice, in the slice detail's shipping block, together with who it is paid to. The buyer's name is included, but not their shipping address: that only appears on the slice detail below.

Response fields

Returns a paginated list of order rows:

Field Type Description
id integer The order row's id.
slice_key string Rows sharing this key belong to the same checkout and ship together.
checkout_id integer or null The checkout the row came from.
status string Order status, see Values.
quantity integer Units sold on this row.
price number Unit price at the moment of the order.
currency string Always EUR in v1.
item.name string or null Display name of the sold item, frozen at order time.
item.subtitle string or null Display subtitle, e.g. the card's set and number.
item.image string or null Item image URL.
item.condition string or null Condition code (see Values). Null for sealed products.
item.language string or null Language code (see Values).
item.type string or null card or product. Null for legacy orders created before this snapshot existed.
item.id string or null The catalog id: feed it straight into GET /cards/{id} or GET /products/{slug}.
item.friendly_id string or null Cards only; null when the set has no shortcut, and for products.
listing_id integer or null The listing that was sold. Null if it was deleted since.
tracking.code string or null Tracking barcode.
tracking.url string or null Track and trace URL.
tracking.status string or null The carrier's latest tracking status.
tracking.updated_at string or null When that tracking status last changed. ISO 8601.
tracking.fulfilment string platform (TCG Plein buys the label) or self_ship (you ship this order yourself via one of your own shipping options; no platform label exists and the ship endpoint requires a tracking code for tracked options).
financial.seller_net number Your net for this article line: price × quantity minus commission. The buyer's shipping fee is never inside a line; see the slice's shipping block.
financial.seller_fee number Total fees deducted from this row.
financial.commission number The commission part of that fee.
financial.refunded_amount number Amount refunded to the buyer so far.
buyer.name string or null The buyer's display name. The shipping address only appears on the slice detail.
created_at string or null ISO 8601.
shipped_at / received_at / cancelled_at / disputed_at string or null Lifecycle timestamps, ISO 8601. Null until the row reaches that state.
curl "https://tcgplein.nl/api/v1/orders?status=pending" \
  -H "Authorization: Bearer tcgp_live_K7mP2xQ9vZ4nR8wT3yL6bC1jD5sF0gH7uM2oA9iE"

Get an order (slice detail)

GET /orders/{id}

Returns every row in the slice that {id} belongs to, the buyer's full shipping address, aggregated totals, and the current shipping/label status. {id} can be any row's id from that slice, not necessarily the first one; the response is identical either way. Besides the required {id} path parameter (integer) there are no query or body parameters.

Response fields

Field Type Description
slice_key string The slice's key.
orders array of objects Every row in the slice, each the same shape as a GET /orders row above.
buyer.name string or null The buyer's display name.
buyer.address object or null The delivery address to ship to.
buyer.address.full_name string Addressee.
buyer.address.street string Street name.
buyer.address.house_number string House number.
buyer.address.house_number_suffix string or null Suffix like A or bis.
buyer.address.zip string Postal code.
buyer.address.city string City.
buyer.address.country string ISO country code, e.g. NL.
buyer.address.phone string or null Phone number, when the buyer provided one.
totals.merchandise number Sum of the slice's item prices.
totals.shipping number What the buyer paid for this slice's shipping.
totals.seller_net number Your net for the whole slice: the sum of every line's financial.seller_net plus shipping.seller_share. This is the figure that is paid out to you.
totals.currency string The currency every amount in this block is expressed in, always EUR in v1. All amounts are decimal, never cents.
shipping.method string or null The shipping method the buyer chose.
shipping.price number Same value as totals.shipping.
shipping.paid_to string Who keeps the buyer's shipping fee. seller: you ship this order yourself via one of your own shipping options, and the fee is paid out to you 1:1 as part of totals.seller_net. platform: TCG Plein buys the label and keeps the fee to pay for it; nothing of it reaches your payout.
shipping.seller_share number The part of totals.seller_net that is the shipping fee: equal to shipping.price when paid_to is seller, otherwise 0. Subtract it from totals.seller_net to get your article earnings for the slice.
shipping.provider string or null The carrier platform a label was generated with, e.g. myparcel. Null before a label exists.
shipping.has_label boolean Whether a label was generated for the slice.
shipping.tracking_code string or null The slice's tracking barcode.
shipping.tracking_status string or null The carrier's latest tracking status.
shipping.label_url string or null Signed label download URL, when a label PDF is available.
shipping.expires_at string or null When that label URL expires. ISO 8601.
curl "https://tcgplein.nl/api/v1/orders/9012" \
  -H "Authorization: Bearer tcgp_live_K7mP2xQ9vZ4nR8wT3yL6bC1jD5sF0gH7uM2oA9iE"

Generate a shipping label

POST /orders/{id}/label

Purchases (or re-reads) a shipping label for the order's slice. Calling it again for the same slice is safe and does not purchase a second shipment; it re-checks the existing one. Besides the required {id} path parameter (integer) there are no query or body parameters. The response's data.status is one of four values:

Status Meaning
ready label_url is populated: the PDF is available.
processing The shipment was created but the label file isn't available yet. Retry the call shortly.
action_required The shipment was created with the carrier, but the label couldn't be retrieved, typically because of a MyParcel balance or payment method issue on your account. Nothing about this resolves on its own: fix the account issue in MyParcel, then call this endpoint again.
self_ship Terminal. This order ships via one of your own shipping options (tracking.fulfilment is self_ship), so no platform label will ever exist. Ship it yourself and report the tracking code via POST /orders/{id}/ship.

label_url is a signed download URL, valid for 5 days and requiring no authentication of its own: anyone with the link can fetch the PDF. A fresh URL (with a fresh 5-day expiry) is minted on every successful call, so don't assume yesterday's link still matches today's expires_at.

A successful label generation also fires an order.label_ready webhook; see Webhooks for why that event can arrive twice for the same order.

Response fields

Field Type Description
status string ready, processing, action_required or self_ship (see above).
label_url string or null Signed PDF download URL. Populated only when status is ready.
expires_at string or null When label_url expires. ISO 8601.
message string or null Human-readable detail, populated for action_required and some edge cases.
tracking_code string or null The shipment's tracking barcode. Can lag behind the label if the carrier assigns it asynchronously.
tracking_url string or null Track and trace URL.
provider string or null The carrier platform, e.g. myparcel.
shipped_lines integer Rows in the slice covered by the shipment.
order object The order's slice detail, the same shape as GET /orders/{id}.
curl -X POST "https://tcgplein.nl/api/v1/orders/9012/label" \
  -H "Authorization: Bearer tcgp_live_K7mP2xQ9vZ4nR8wT3yL6bC1jD5sF0gH7uM2oA9iE"

Mark an order shipped

POST /orders/{id}/ship

Marks every still-pending row in the slice as shipped in one call (not just {id}'s own row), and notifies the buyer once per shipped row. If nothing in the slice is still pending, this returns 409 conflict.

Shipping needs a fully verified Stripe payout account: until the account behind the key can receive payouts, both this endpoint and POST /orders/{id}/label answer 409 conflict with the message Complete and verify your Stripe payout setup before shipping. Listing never requires it; a sale only ships once the seller can be paid out.

Whether tracking_code is allowed follows the order's tracking.fulfilment. For self_ship orders on one of your own tracked shipping options the code is required: it is the buyer's only delivery evidence. Your letter options carry no tracking, so the field is refused there. For platform orders the field is also refused (422): the tracking code comes from the label generated on TCG Plein.

Body

Parameter Type Required Description
tracking_code string Conditional Max 100 characters, recorded against every row shipped by this call. Required for self_ship orders on a tracked own option; refused (422) for own letter options and for platform-label orders.

Response fields

Returns the order's updated slice detail under data, plus a shipped_lines count:

Field Type Description
slice_key string The slice's key.
orders array of objects Every row in the slice, now with their updated status, each the same shape as a GET /orders row above.
buyer.name string or null The buyer's display name.
buyer.address object or null The delivery address.
buyer.address.full_name string Addressee.
buyer.address.street string Street name.
buyer.address.house_number string House number.
buyer.address.house_number_suffix string or null Suffix like A or bis.
buyer.address.zip string Postal code.
buyer.address.city string City.
buyer.address.country string ISO country code, e.g. NL.
buyer.address.phone string or null Phone number, when the buyer provided one.
totals.merchandise number Sum of the slice's item prices.
totals.shipping number What the buyer paid for this slice's shipping.
totals.seller_net number Your net for the whole slice: the sum of every line's financial.seller_net plus shipping.seller_share. This is the figure that is paid out to you.
totals.currency string The currency every amount in this block is expressed in, always EUR in v1. All amounts are decimal, never cents.
shipping.method string or null The shipping method the buyer chose.
shipping.price number Same value as totals.shipping.
shipping.paid_to string Who keeps the buyer's shipping fee. seller: you ship this order yourself via one of your own shipping options, and the fee is paid out to you 1:1 as part of totals.seller_net. platform: TCG Plein buys the label and keeps the fee to pay for it; nothing of it reaches your payout.
shipping.seller_share number The part of totals.seller_net that is the shipping fee: equal to shipping.price when paid_to is seller, otherwise 0. Subtract it from totals.seller_net to get your article earnings for the slice.
shipping.provider string or null The carrier platform a label was generated with, e.g. myparcel. Null before a label exists.
shipping.has_label boolean Whether a label was generated for the slice.
shipping.tracking_code string or null The slice's tracking barcode.
shipping.tracking_status string or null The carrier's latest tracking status.
shipping.label_url string or null Signed label download URL, when a label PDF is available.
shipping.expires_at string or null When that label URL expires. ISO 8601.
shipped_lines integer Rows marked shipped by this call.
curl -X POST "https://tcgplein.nl/api/v1/orders/9012/ship" \
  -H "Authorization: Bearer tcgp_live_K7mP2xQ9vZ4nR8wT3yL6bC1jD5sF0gH7uM2oA9iE" \
  -H "Content-Type: application/json" \
  -d '{"tracking_code": "3SMYPXXXXXXXXXX"}'

Cookies op TCG Plein. We gebruiken noodzakelijke cookies om de site te laten werken, analytische cookies om te zien hoe bezoekers de site gebruiken en marketingcookies om te meten of onze advertenties werken. Analytische en marketingcookies plaatsen we alleen als je ze accepteert. Lees meer in ons cookiebeleid.