Tags & locations

Tags and locations are labels you attach to inventory lines to organise your stock. Both live in your account and are referenced by name — you never handle an internal id.

  • A tag groups lines however you like. A line can carry any number of tags.
  • A location is where you keep the stock. A line has at most one location.

Names are matched case-insensitively, with surrounding spaces ignored, so Shelf A, shelf a, and Shelf A all refer to the same label.

Both are private to you: buyers never see a line's tags or location.

Managing tags

GET /v1/inventory/tags lists every tag in your account. Each carries a name and an optional display color and icon.

[
  { "name": "Trade binder", "color": "#22c55e", "icon": "star" },
  { "name": "Graded pile", "color": null, "icon": null }
]

POST /v1/inventory/tags creates a tag. The name must be one you don't already use — a duplicate returns 409 CONFLICT.

curl -X POST https://public-api.cardnexus.com/v1/inventory/tags \
  -H "Authorization: Bearer cnk_live_4f2d8c91e5b34a7f9e6c2d1a8b5f7e3c" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Trade binder", "color": "#22c55e" }'

Send "upsert": true to make the call safe to repeat: when the tag already exists it is returned — updated with any color or icon you sent — instead of failing with CONFLICT. One call then guarantees the tag exists before you reference it on lines.

curl -X POST https://public-api.cardnexus.com/v1/inventory/tags \
  -H "Authorization: Bearer cnk_live_4f2d8c91e5b34a7f9e6c2d1a8b5f7e3c" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Trade binder", "color": "#22c55e", "upsert": true }'

PATCH /v1/inventory/tags/{tagName} renames a tag or changes its color or icon. Put the current name in the path, URL-encoded, and send only the fields you want to change. Renaming keeps the tag on every line that already carries it. A new name that clashes with another tag returns 409 CONFLICT.

curl -X PATCH "https://public-api.cardnexus.com/v1/inventory/tags/Trade%20binder" \
  -H "Authorization: Bearer cnk_live_4f2d8c91e5b34a7f9e6c2d1a8b5f7e3c" \
  -H "Content-Type: application/json" \
  -d '{ "name": "For trade" }'

DELETE /v1/inventory/tags/{tagName} deletes a tag and detaches it from every line that carries it. The lines themselves are kept. A name that matches no tag returns 404 NOT_FOUND.

Managing locations

Locations use the same four endpoints as tags:

Deleting a location moves every line that sits there back to having no location — the lines are kept.

Attaching them to lines

You don't move lines with a dedicated endpoint. Instead, set a line's location and tags through the same endpoints you use to create and edit lines: POST /v1/inventory, PATCH /v1/inventory/{inventoryId}, POST /v1/inventory/bulk/update, and bulk import.

A name must already exist. Referencing a tag or location that isn't in your account does not create it — the write is rejected with TAG_NOT_FOUND or LOCATION_NOT_FOUND (422 on a single edit, a per-item or per-row error in bulk). Create the label first — a single POST with "upsert": true guarantees it exists without failing when it already does.

On create

When creating lines, location is a name and tags is a list of names:

curl -X POST https://public-api.cardnexus.com/v1/inventory \
  -H "Authorization: Bearer cnk_live_4f2d8c91e5b34a7f9e6c2d1a8b5f7e3c" \
  -H "Content-Type: application/json" \
  -d '{
    "lines": [
      {
        "productId": 50212,
        "finish": "Standard",
        "condition": "NM",
        "language": "en",
        "quantity": 5,
        "location": "Shelf A",
        "tags": ["Trade binder", "Graded pile"],
        "notes": "Bought at the March show"
      }
    ]
  }'

On update: location

location on PATCH /v1/inventory/{inventoryId} takes a name to move the line, null to move it to no location, or is omitted to leave it unchanged.

{ "location": "Shelf B" }
{ "location": null }

On update: tags

tags on an edit is a change object with exactly one of set, add, or remove:

{ "tags": { "set": ["Trade binder", "Graded pile"] } }
{ "tags": { "add": ["Hot"] } }
{ "tags": { "remove": ["Trade binder"] } }
Shape Effect
{ "set": [...] } Replace the line's tags with exactly these.
{ "set": [] } Remove all tags from the line.
{ "add": [...] } Add these tags, keeping the ones the line already has.
{ "remove": [...] } Remove these tags, leaving the ones you don't list.
omit tags Leave the line's tags unchanged.

The same location and tags shapes work per item on POST /v1/inventory/bulk/update, so you can move or retag many lines in one call.

Private notes

Separate from tags and locations, every line has a notes field: a private free-text note, visible only to you and never shown to buyers. Set it on create or edit, and pass null to clear it. Its buyer-facing counterpart is comment — see the Inventory overview.

Reading them back

A line always reports its current labels: location (the name, or null), tags (an array of names, empty when none), and notes. Bulk export includes all three so a file exports, edits, and imports back with them intact.

Filtering by tag or location

GET /v1/inventory takes flat filters: location (one location name) and tags (repeat the parameter to pass several; a line matches when it carries any of them).

curl "https://public-api.cardnexus.com/v1/inventory?location=Store%20A&tags=to-verify&tags=reserved" \
  -H "Authorization: Bearer cnk_live_4f2d8c91e5b34a7f9e6c2d1a8b5f7e3c"

POST /v1/inventory/search takes the richer shape: { "op": "and" | "or", "values": [...] }. or matches lines carrying any of the values; and requires all of them. Pass null as a value to match lines with no tag (or no location):

{
  "tags": { "op": "and", "values": ["to-verify", "reserved"] },
  "location": { "op": "or", "values": ["Store A", null] }
}

POST /v1/inventory/bulk/export accepts the same filters as the search endpoint, so a single location — or every untagged line — can be exported as a file.