Inventory
Your inventory is a list of lines. A line is a quantity of one product in one set of attributes: a finish, a language, and either a condition (raw cards) or grading details (graded cards). A line that holds five Near Mint English copies of a card is one line with quantity: 5, not five separate records.
{
"id": "665f3a2b1c8d4e9f7a6b5c4d",
"customId": "YRG|5555-5DS1-2EX-006-f-2-2008-08-01",
"comment": "Slight edge wear on the back corner",
"notes": "Bought at the March show",
"location": "Shelf A",
"tags": ["Trade binder", "Graded pile"],
"productId": 50212,
"game": "ygo",
"finish": "Standard",
"condition": "NM",
"language": "en",
"quantity": 5,
"graded": null,
"forSale": true,
"listing": { "price": { "amount": 42.50, "currency": "EUR" } },
"updatedAt": "2026-06-01T17:40:02.000Z"
}
What a line holds
| Field | Type | Description |
|---|---|---|
id |
string | Stable opaque identifier for the line. Don't parse it. |
customId |
string | null | Your own identifier for the line (see below). null when you haven't set one. |
comment |
string | null | Free-text note attached to the line, shown to buyers on your Marketplace listing. null when there is none. |
notes |
string | null | Private free-text note, visible only to you and never shown to buyers. null when there is none. |
location |
string | null | The name of the location the line sits in. null when it has none. See Tags & locations. |
tags |
string[] | The names of the tags attached to the line. Empty when it has none. See Tags & locations. |
productId |
number | The catalogue product the line stocks. Returned by GET /v1/products. |
game |
string | The game the product belongs to, as a slug, e.g. ygo. |
finish |
string | The card's finish, e.g. Standard, Foil, Reverse Holo. |
condition |
string | null | NM, LP, MP, HP, or DMG. null when the card is graded. |
language |
string | null | The card's language as a two-letter code, e.g. en, fr, de. |
quantity |
number | How many cards the line holds. |
graded |
object | null | Grading details when the card is graded. null for raw cards. |
forSale |
boolean | true when the line is on the Marketplace; false when it's in your Collection. |
listing |
object | null | The listing's per-card price when forSale is true. null otherwise. |
updatedAt |
string | When the line was last modified, ISO 8601 UTC. |
Conditions
Raw cards carry one of five conditions:
| Token | Meaning |
|---|---|
NM |
Near Mint |
LP |
Lightly Played |
MP |
Moderately Played |
HP |
Heavily Played |
DMG |
Damaged |
A graded card has no condition — its condition is null and its graded object carries the grade, certification number, and grading company instead:
{
"grade": "9.5",
"certification": "0084712663",
"gradingService": "PSA"
}
certification is optional on writes — you can add a graded card without it, and it comes back as null on lines that don't carry one.
Your customId
customId is an identifier you control. CardNexus stores it on the line and never modifies it. It must be unique across your live lines, and you can use it to look a line up — filter GET /v1/inventory by customId, or target a line by customId in a bulk update — without tracking the CardNexus id.
It accepts any printable characters up to 255 of them, so you can encode your own location and sorting data in a composite value, for example YRG|5555-5DS1-2EX-006-f-2-2008-08-01. When you delete a line, its customId becomes free for reuse on another line.
comment is a separate free-text note (up to 2000 characters) that buyers see when they view your listing — a place for condition details, like edge wear or whitening, or anything else you want a buyer to know about these specific cards. Unlike customId, comment has no uniqueness rule. For anything private — where you keep a line, how you group it, or a note only you see — use the dedicated location, tags, and notes fields instead (see Tags & locations); notes in particular is the private counterpart to comment.
How lines merge
Two lines that hold the same product with the same attributes — same productId, finish, condition, language, grading, and listing state — and neither of which carries a customId are treated as the same line. When a write would produce a second such line, the quantities combine into one line instead.
A customId, a comment, or a location keeps a line separate. Two lines that are otherwise identical but differ in customId, comment, or location stay as two distinct lines and never merge — so the same card on two different shelves stays as two lines. notes and tags don't affect this: two lines that differ only in their notes or tags still merge. This lets you keep, say, two batches of the same card apart by giving each its own customId, while letting plain restocks fold into a single line automatically.
For sale or in your Collection
Every line is either for sale on the Marketplace (forSale: true, with a listing price) or sitting in your Collection (forSale: false, listing: null). A line can move between the two: listing part of a Collection line moves those cards onto a for-sale line; taking a listing off sale moves the cards back. See Listings.
Scopes
Inventory and listing endpoints require an API key with the matching scope:
| Scope | Grants |
|---|---|
inventory:read |
Read your inventory lines. |
inventory:write |
Create, update, delete lines, and set line photos. |
listings:read |
Read your Marketplace listings. |
listings:write |
List, reprice, and delist lines. |
See Authentication for how scopes attach to a key.
Reading your inventory
GET /v1/inventory returns your lines as a cursor-paginated list ordered by line id. Filter with any combination of game, productId (repeatable), forSale, condition, language, finish, graded, customId, customIdPrefix, customIdContains, commentContains, location, and tags (repeatable); filters are combined with AND. Follow pagination.nextCursor until it comes back null. limit defaults to 50, maximum 100.
GET /v1/inventory/{inventoryId} returns a single line by its id.
POST /v1/inventory/search searches your lines with free-text product-name matching, and/or tag and location filters, quantity and price ranges, and game-specific attribute filters, as an offset-paginated list.
Both endpoints return the same line shape; they serve different jobs:
GET /v1/inventoryreads and syncs. It always reflects your latest changes, keeps a stable order while you write, and walks every line to the end. Use it to keep an external system in step with CardNexus.POST /v1/inventory/searchfinds. Relevance-ranked name search, richer matching, jump-to-page pagination over the first 10,000 matches. Results can lag your latest changes by a few seconds.
Related
- Managing lines — create, update, delete, and add photos
- Listings — put lines on the Marketplace
- Bulk operations — import, export, and bulk update
- Webhooks — quantity, import, and export events