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

Listings

Manage your own listings. Reading needs listings:read; creating, updating and deleting need listings:write. The account must have a fully verified Stripe payout setup before it can create listings (the same requirement as the dashboard): a key without one gets 403 authorization_error on POST /listings.

List your listings

GET /listings

Query parameters

Parameter Type Required Description
status string Optional active, sold or hidden; see Values.
updated_since string Optional ISO date/datetime. Only listings updated at or after this point.
card string Optional A card identifier (canonical or friendly id). Restricts to listings of that card.
product string Optional A sealed product slug. Restricts to listings of that product.
page / per_page integer Optional See Pagination.

This is the same listing shape used in the catalog listings embed (see Cards), plus owner-only fields (status, raw quantity, listable, created_at, updated_at) since every listing on this endpoint belongs to you.

Response fields

Returns a paginated list of listing objects. The fields marked owner-only below are exactly the ones missing from the public shape the catalog embeds return.

Field Type Description
id integer The listing's id.
price number Unit price as a decimal amount in euros, never cents: 4.50 is four euros fifty.
currency string Always EUR in v1.
condition string or null Card condition code (see Values). Null for sealed-product listings.
language string Language code (see Values).
printing string Card variant (see Values). standard when never set.
graded object or null Non-null only when condition is G.
graded.company string Grading company code (see Values).
graded.grade string The grade, e.g. 9.5.
graded.label string Formatted display label, e.g. PSA 8.5.
quantity_available integer Units buyable right now, with active cart reservations subtracted.
description string or null Your free-form listing description.
photos array of strings Photo thumbnail URLs.
seller.name string The seller's display name.
seller.slug string or null The seller's shop slug.
seller.url string or null The seller's shop page on the marketplace.
seller.tier string Seller tier name (see Values).
seller.rating number or null Average review rating. Null without reviews.
seller.reviews integer Number of reviews received.
status string Owner-only. See Values.
quantity integer Owner-only. The raw, un-reserved stock count.
listable object or null Owner-only. What the listing is for.
listable.type string card or product.
listable.id string The card's canonical id, or the product's slug.
listable.friendly_id string or null Cards only; null when the set has no shortcut. Absent for products.
listable.name string The card's or product's name.
listable.number string Cards only: the collector number.
listable.set string or null Cards only: the set's shortcut.
created_at string Owner-only. ISO 8601.
updated_at string Owner-only. ISO 8601.
curl "https://tcgplein.nl/api/v1/listings?status=active" \
  -H "Authorization: Bearer tcgp_live_K7mP2xQ9vZ4nR8wT3yL6bC1jD5sF0gH7uM2oA9iE"

Create listings

POST /listings

Creates up to 100 listings in one call. Each item is validated and saved independently: a mistake in one item never sinks the rest of the batch. The response is always HTTP 200, even when every item failed. Check each item's own status, not the HTTP status code, to see what happened.

Each item needs exactly one of card (a card identifier) or product (a sealed product slug), plus language, price and quantity. Cards additionally require condition; when condition is G (graded), grading_company and grading_grade are also required. photo_urls is optional: up to 10 publicly reachable image URLs, fetched and attached asynchronously after the listing is created. There's no multipart upload in v1, only importable URLs, and the same public-URL safety rules as webhook endpoints apply (see Webhooks).

Body

Parameter Type Required Description
items array of objects Required 1 to 100 items.
items.*.language string Required The listing's language code, see Values.
items.*.price number Required Unit price in euros, 0.01 to 99999.99. Rounded to 2 decimals.
items.*.quantity integer Required 1 to 999.
items.*.card string Optional A card identifier (canonical or friendly id). Each item must contain exactly one of card or product.
items.*.product string Optional A sealed product slug. Each item must contain exactly one of card or product.
items.*.language_hint string Optional Only disambiguates an ambiguous card identifier for this item (same role as ?language= on GET /cards/{identifier}). Not the listing's own language.
items.*.condition string Optional Required for card items, ignored for products. A condition code from Values.
items.*.printing string Optional Card variant, see Values. Cards only; omitting it means standard.
items.*.grading_company string Optional Required when condition is G. A grading company from Values.
items.*.grading_grade string Optional Required when condition is G. One decimal, 1.0 to 10.0 in half steps (see Values).
items.*.description string Optional Max 1000 characters.
items.*.photo_urls array of strings Optional Up to 10 publicly reachable image URLs, imported asynchronously.

The item-count cap is enforced by request validation, so a batch of more than 100 items always gets 422 validation_error.

Response fields

Not a data envelope: results, created and failed are top-level fields.

Field Type Description
results array of objects One result per submitted item, in order.
results.*.status string created or failed.
results.*.index integer The item's position in your items array.
results.*.listing object Only when created: a compact summary of the new listing.
results.*.listing.id integer The new listing's id.
results.*.listing.price number Unit price in euros, as stored.
results.*.listing.quantity integer Stock, as stored.
results.*.listing.status string Always active on creation; see Values.
results.*.errors object Only when failed: field name to messages, the same shape as a validation_error.
results.*.candidates array of objects Only when failed on an ambiguous identifier: the candidate list, same shape as the 409 ambiguous_identifier error.
created integer How many items were created.
failed integer How many items failed.
warnings array of strings Only present when your account needs attention. Currently one warning exists: your account has no shipping options enabled, so buyers cannot order your listings. The listings are still created; enable a shipping option under Verzendinstellingen in the seller dashboard.

Shipping is configured once per account, not per listing, so the API never takes shipping input. If your account has every shipping option switched off, creation still succeeds but the response carries a warnings entry: without at least one enabled option buyers get an empty shipping selection at checkout and cannot order anything you list.

curl -X POST "https://tcgplein.nl/api/v1/listings" \
  -H "Authorization: Bearer tcgp_live_K7mP2xQ9vZ4nR8wT3yL6bC1jD5sF0gH7uM2oA9iE" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "card": "pbl_63",
        "condition": "NM",
        "language": "EN",
        "price": 4.50,
        "quantity": 3,
        "photo_urls": ["https://example.com/photos/pbl-63-front.jpg"]
      },
      {
        "product": "unknown-product-slug",
        "language": "EN",
        "price": 19.99,
        "quantity": 1
      }
    ]
  }'

A failed item because of an ambiguous card or set shortcut also carries a candidates field, the same shape as the 409 ambiguous_identifier error (see Identifiers). Here it's attached to the item's result object rather than thrown as a top-level error, since one ambiguous item shouldn't fail the whole batch.

Update a listing

PATCH /listings/{id}

{id} is the listing's id. All body fields are optional; only send what you want to change.

Body

Parameter Type Required Description
price number Optional Unit price in euros, 0.01 to 99999.99.
quantity integer Optional 0 to 999. 0 flips the listing to sold automatically.
status string Optional active, hidden or sold; see Values and the reconciliation rules below.
description string or null Optional Max 1000 characters. Send null or an empty string to clear it.

Stock and status are reconciled automatically after the update, mirroring what happens when a listing sells out on the marketplace itself. Setting quantity: 0 is the idiom for taking a listing off-sale without deleting it: the listing is flipped to sold automatically, even if you didn't send status in the same request. The reverse also holds: restocking a sold listing (sending a quantity greater than 0) flips it back to active automatically. The same rule also means sending status: "sold" on its own, while the listing's quantity is still above 0, validates but is immediately reconciled back to active: pair it with quantity: 0 if you want it to actually stay off-sale.

Response fields

Returns the updated listing under data, with no links / meta. Because it's your own listing, the owner-only fields are always present:

Field Type Description
id integer The listing's id.
price number Unit price as a decimal amount in euros, never cents: 4.50 is four euros fifty.
currency string Always EUR in v1.
condition string or null Card condition code (see Values). Null for sealed-product listings.
language string Language code (see Values).
printing string Card variant (see Values). standard when never set.
graded object or null Non-null only when condition is G.
graded.company string Grading company code (see Values).
graded.grade string The grade, e.g. 9.5.
graded.label string Formatted display label, e.g. PSA 8.5.
quantity_available integer Units buyable right now, with active cart reservations subtracted.
description string or null Your free-form listing description.
photos array of strings Photo thumbnail URLs.
seller.name string The seller's display name.
seller.slug string or null The seller's shop slug.
seller.url string or null The seller's shop page on the marketplace.
seller.tier string Seller tier name (see Values).
seller.rating number or null Average review rating. Null without reviews.
seller.reviews integer Number of reviews received.
status string After the automatic reconciliation described above. See Values.
quantity integer The raw, un-reserved stock count.
listable object or null What the listing is for.
listable.type string card or product.
listable.id string The card's canonical id, or the product's slug.
listable.friendly_id string or null Cards only; null when the set has no shortcut. Absent for products.
listable.name string The card's or product's name.
listable.number string Cards only: the collector number.
listable.set string or null Cards only: the set's shortcut.
created_at string ISO 8601.
updated_at string ISO 8601.
curl -X PATCH "https://tcgplein.nl/api/v1/listings/5231" \
  -H "Authorization: Bearer tcgp_live_K7mP2xQ9vZ4nR8wT3yL6bC1jD5sF0gH7uM2oA9iE" \
  -H "Content-Type: application/json" \
  -d '{"quantity": 0}'

Delete a listing

DELETE /listings/{id}

{id} is the listing's id; there are no other parameters and no body. Returns 204 No Content on success, with no response fields. A listing with an open order can't be deleted: that returns 409 conflict instead, until the order completes. A listing id that doesn't belong to you 404s, the same as if it didn't exist.

curl -X DELETE "https://tcgplein.nl/api/v1/listings/5231" \
  -H "Authorization: Bearer tcgp_live_K7mP2xQ9vZ4nR8wT3yL6bC1jD5sF0gH7uM2oA9iE"

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.