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 /listingsQuery 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"