Cards Cloud

Cards Cloud stores the cards you identify as sessions in your Ximilar account. A session is one batch of work — a live stream, a binder scanned in one sitting, a folder of photos — and holds one identification row per card: the matched card, its alternatives, prices, links, an image and, optionally, its grading.

Sessions are shared between Ximilar's apps. The open-source Cardstream live-stream app and Cardloader desktop app both write to Cards Cloud, and each session records which app made it in its client field. You can use the same API to keep your own app's results there.

Cards Cloud does not identify cards itself: identify them first with Collectibles Recognition (and grade them with Card Grading if you like), then upload the results.

Endpoints

GET     https://api.ximilar.com/cards-cloud/v2/ping/                              → Check access
POST    https://api.ximilar.com/cards-cloud/v2/session/                           → Create a session
GET     https://api.ximilar.com/cards-cloud/v2/session/                           → List sessions
GET     https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/            → Get a session
PATCH   https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/            → Rename a session
DELETE  https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/            → Delete a session
POST    https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/close/      → Close a session
POST    https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/reopen/     → Reopen a session
GET     https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/summary/    → Session totals
POST    https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/identifications/  → Upload identified cards
POST    https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/images/     → Upload a card's image
GET     https://api.ximilar.com/cards-cloud/v2/identification/                    → List a session's cards
PATCH   https://api.ximilar.com/cards-cloud/v2/identification/__ID__/             → Correct a card's match

Every endpoint takes an optional workspace query parameter (a workspace ID); without it, the default workspace of your API token is used.

How a session is filled

  1. Create a session. It starts live.
  2. Upload identified cards in batches as you go. Each row carries an event_id you choose — a string that is unique within the session, for example a hash of the image file name. Cards Cloud keys rows by it, so uploading the same event_id again updates that row (for example when its grading arrives later) instead of adding a duplicate.
  3. Upload each card's image by its event_id. The answer is the stored row, with its id.
  4. Close the session when the batch is finished. A closed session can be reopened to add more cards.

Re-uploading a row that Cards Cloud already has does not change its card fields. When a user picks a different match for a card, send the correction with PATCH identification/__ID__/ instead.

To continue a session later, list its rows and skip the cards whose event_id is already there.


The session object

  • Name
    id
    Type
    string
    Description

    Unique identifier of the session.

  • Name
    name
    Type
    string
    Max
    Maximum:255
    Description

    Name of the session.

  • Name
    description
    Type
    string
    Description

    Free-text description.

  • Name
    game
    Type
    string
    Description

    What the session holds: TCG, Sports, Comics, Slabs, or empty for a mix.

  • Name
    platform
    Type
    string
    Description

    Where the cards were identified, for example a streaming platform; other for anything else.

  • Name
    status
    Type
    string
    Description

    live while cards are being added, closed when finished.

  • Name
    started
    Type
    string
    Description

    When the session started (ISO 8601).

  • Name
    ended
    Type
    string
    Description

    When it was closed (ISO 8601), or null.

  • Name
    identification_count
    Type
    integer
    Description

    Number of cards in the session.

  • Name
    total_price
    Type
    number
    Description

    Sum of the cards' prices (USD).

  • Name
    client
    Type
    dict
    Description

    The app that made the session: name, version and os. Cardstream and Cardloader ("name": "cardloader") set it.

  • Name
    meta_data
    Type
    dict
    Description

    Any JSON object the client wants to keep with the session, such as its settings.

The identification object

One row per card. All text fields are optional; values longer than the limit are rejected, and one invalid row rejects the whole batch.

  • Name
    id
    Type
    string
    Description

    Unique identifier of the row (assigned by Cards Cloud).

  • Name
    event_id
    Type
    string
    Description

    Your key for the card, unique within the session.

  • Name
    seen
    Type
    string
    Description

    When the card was identified (ISO 8601).

  • Name
    calls
    Type
    integer
    Description

    How many API calls identifying the card took.

  • Name
    id_type
    Type
    string
    Description

    The kind of identification: tcg, sport, comics or slab.

  • Name
    name
    Type
    string
    Max
    Maximum:255
    Description

    Card name.

  • Name
    full_name
    Type
    string
    Max
    Maximum:500
    Description

    Full card name, as Collectibles Recognition returns it.

  • Name
    set_name
    Type
    string
    Max
    Maximum:255
    Description

    Set (for comics: publisher).

  • Name
    set_code
    Type
    string
    Max
    Maximum:50
    Description

    Set code.

  • Name
    card_number
    Type
    string
    Max
    Maximum:50
    Description

    Card number.

  • Name
    series
    Type
    string
    Max
    Maximum:255
    Description

    Series.

  • Name
    year
    Type
    string
    Max
    Maximum:20
    Description

    Year.

  • Name
    subcategory
    Type
    string
    Max
    Maximum:100
    Description

    Game or sport, as the taxonomy spells it (e.g. Pokemon, Baseball).

  • Name
    distance
    Type
    number
    Description

    Distance of the best match (lower is closer).

  • Name
    confidence
    Type
    string
    Description

    high, medium or low.

  • Name
    links
    Type
    dict
    Description

    Marketplace links of the best match, {site: url} (each URL up to 2048 characters).

  • Name
    alternatives
    Type
    array
    Max
    Maximum:10
    Description

    Other candidate matches, as Collectibles Recognition returns them.

  • Name
    price_stats
    Type
    array
    Max
    Maximum:10
    Description

    Price statistics of the best match, as Collectibles Recognition returns them.

  • Name
    price
    Type
    number
    Description

    Price of the card (USD).

  • Name
    grading
    Type
    dict
    Max
    Maximum:64 KiB
    Description

    The card's grading: endpoint (the Card Grading endpoint used), grades (with final, condition, sub-grades) and optionally the grading records. grade is derived from grades.final.

  • Name
    grade
    Type
    number
    Description

    Final grade (read-only, from grading).

  • Name
    image
    Type
    string
    Description

    URL of the card's image, once uploaded (read-only).

  • Name
    thumbnail
    Type
    string
    Description

    URL of a small version of the image (read-only).

  • Name
    sold
    Type
    boolean
    Description

    Whether the card was sold.

  • Name
    note
    Type
    string
    Description

    Free-text note.


GET/cards-cloud/v2/ping/

Check access

Checks that your API token can use Cards Cloud.

Returns

HTTP error code 2XX if Cards Cloud is available to your account, and another HTTP error code if not.

Request

GET
/cards-cloud/v2/ping/
curl -H 'Authorization: Token __API_TOKEN__' \
     https://api.ximilar.com/cards-cloud/v2/ping/

POST/cards-cloud/v2/session/

Create a session

Creates a new live session.

Attributes

  • Name
    name
    Type
    string
    Max
    Maximum:255
    Description

    Name of the session.

  • Name
    description
    Type
    string
    Description

    Free-text description.

  • Name
    game
    Type
    string
    Description

    TCG, Sports, Comics, Slabs, or empty for a mix.

  • Name
    platform
    Type
    string
    Description

    Where the cards are identified; other for anything else.

  • Name
    client
    Type
    dict
    Description

    The app creating the session: name, version, os.

  • Name
    meta_data
    Type
    dict
    Description

    Any JSON object to keep with the session.

Returns

The new session, with its id. 402 means the account doesn't have enough credits to create a session; 403 means Cards Cloud isn't enabled for the account.

Request

POST
/cards-cloud/v2/session/
curl --location 'https://api.ximilar.com/cards-cloud/v2/session/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token __API_TOKEN__' \
--data '{
  "name": "Binder #3 — vintage Pokémon",
  "description": "Scanned with my app",
  "game": "TCG",
  "platform": "other",
  "client": {"name": "my-app", "version": "1.0.0", "os": "macos"},
  "meta_data": {"source": "folder"}
}'

Response

{
  "id": "8f3c2a10-5b7e-4c1d-9a2f-0e6d4b1c7a35",
  "name": "Binder #3 — vintage Pokémon",
  "description": "Scanned with my app",
  "game": "TCG",
  "platform": "other",
  "status": "live",
  "client": {"name": "my-app", "version": "1.0.0", "os": "macos"},
  "meta_data": {"source": "folder"}
}

GET/cards-cloud/v2/session/

List sessions

Lists your sessions, a page at a time.

Optional attributes

  • Name
    page
    Type
    integer
    Default
    Default:1
    Description

    Page number.

  • Name
    search
    Type
    string
    Description

    Only sessions matching this text.

Returns

count (number of sessions), next (URL of the next page, or null) and results, a list of sessions.

Request

GET
/cards-cloud/v2/session/
curl -H 'Authorization: Token __API_TOKEN__' \
     'https://api.ximilar.com/cards-cloud/v2/session/?page=1&search=binder'

Response

{
  "count": 1,
  "next": null,
  "results": [
    {
      "id": "8f3c2a10-5b7e-4c1d-9a2f-0e6d4b1c7a35",
      "name": "Binder #3 — vintage Pokémon",
      "description": "Scanned with my app",
      "game": "TCG",
      "platform": "other",
      "status": "closed",
      "started": "2026-10-14T16:20:00Z",
      "ended": "2026-10-14T16:41:12Z",
      "identification_count": 18,
      "total_price": 412.5,
      "client": {"name": "my-app", "version": "1.0.0", "os": "macos"},
      "meta_data": {"source": "folder"}
    }
  ]
}

GET/cards-cloud/v2/session/{id}/

Get a session

Returns one session. Use its status to tell whether you can keep adding cards (live) or need to reopen it first.

Returns

The session, or 404 if it doesn't exist (for example, it was deleted).

Request

GET
/cards-cloud/v2/session/{id}/
curl -H 'Authorization: Token __API_TOKEN__' \
     https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/

PATCH/cards-cloud/v2/session/{id}/

Rename a session

Changes a session's name.

Attributes

  • Name
    name
    Type
    string
    Max
    Maximum:255
    Description

    The new name.

Returns

The updated session.

Request

PATCH
/cards-cloud/v2/session/{id}/
curl -XPATCH 'https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token __API_TOKEN__' \
--data '{"name": "Binder #3 — done"}'

DELETE/cards-cloud/v2/session/{id}/

Delete a session

Deletes a session with all its cards and images.

Returns

HTTP error code 2XX, if the method was OK, and other HTTP error code, if the method failed.

Request

DELETE
/cards-cloud/v2/session/{id}/
curl -XDELETE -H 'Authorization: Token __API_TOKEN__' \
     https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/

POST/cards-cloud/v2/session/{id}/close/

Close a session

Marks a session as finished: its status becomes closed. Corrections with PATCH identification/__ID__/ still work on a closed session.

Returns

HTTP error code 2XX, if the method was OK, and other HTTP error code, if the method failed.

Request

POST
/cards-cloud/v2/session/{id}/close/
curl -XPOST -H 'Authorization: Token __API_TOKEN__' \
     https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/close/

POST/cards-cloud/v2/session/{id}/reopen/

Reopen a session

Makes a closed session live again, so you can upload more cards to it.

Returns

HTTP error code 2XX, if the method was OK, and other HTTP error code, if the method failed.

Request

POST
/cards-cloud/v2/session/{id}/reopen/
curl -XPOST -H 'Authorization: Token __API_TOKEN__' \
     https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/reopen/

GET/cards-cloud/v2/session/{id}/summary/

Session summary

Totals of a session's cards.

Returns

  • Name
    identifications
    Type
    integer
    Description

    Number of cards.

  • Name
    distinct_cards
    Type
    integer
    Description

    Number of different cards.

  • Name
    total_price
    Type
    number
    Description

    Sum of the cards' prices (USD).

  • Name
    paid_calls
    Type
    integer
    Description

    API calls spent identifying the cards.

  • Name
    average_grade
    Type
    number
    Description

    Average final grade of the graded cards, or null.

Request

GET
/cards-cloud/v2/session/{id}/summary/
curl -H 'Authorization: Token __API_TOKEN__' \
     https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/summary/

Response

{
  "identifications": 18,
  "distinct_cards": 15,
  "total_price": 412.5,
  "paid_calls": 36,
  "average_grade": 8.5
}

POST/cards-cloud/v2/session/{id}/identifications/

Upload identified cards

Adds cards to a live session, or updates the ones whose event_id it already has. Send the rows in batches.

A row whose event_id is already in the session keeps its card fields (name, set, number, …); use this to add data that arrives later, such as grading. To change the matched card, use PATCH identification/__ID__/.

Attributes

  • Name
    identifications
    Type
    array
    Description

    Rows in the shape of the identification object, each with an event_id. id, grade, image and thumbnail are set by Cards Cloud.

Returns

How many rows were received, created, updated, and were duplicates. If any row is invalid (for example a field over its length limit), the whole batch is rejected.

Request

POST
/cards-cloud/v2/session/{id}/identifications/
curl --location 'https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/identifications/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token __API_TOKEN__' \
--data '{
  "identifications": [
    {
      "event_id": "3f9a1c0e7b2d4e58",
      "seen": "2026-10-14T16:21:03.120Z",
      "calls": 1,
      "id_type": "tcg",
      "name": "Charizard ex",
      "full_name": "Charizard ex Obsidian Flames (OBF) #125",
      "set_name": "Obsidian Flames",
      "set_code": "OBF",
      "card_number": "125",
      "series": "Scarlet & Violet",
      "year": "2023",
      "subcategory": "Pokemon",
      "distance": 0.21,
      "confidence": "high",
      "links": {"tcgplayer.com": "https://example.com/product/125"},
      "alternatives": [
        {"name": "Charizard ex", "full_name": "Charizard ex Obsidian Flames (OBF) #223", "set": "Obsidian Flames",
         "set_code": "OBF", "card_number": "223", "year": 2023}
      ],
      "price_stats": [{"stats_type": "ungraded", "value": {"median": 12.5}}],
      "grading": {
        "endpoint": "grade",
        "grades": {"corners": 8.0, "edges": 8.0, "surface": 6.0, "centering": 9.0, "final": 7.5,
                   "condition": "Near Mint"}
      }
    }
  ]
}'

Response

{
  "received": 1,
  "created": 1,
  "updated": 0,
  "duplicates": 0
}

POST/cards-cloud/v2/session/{id}/images/

Upload a card's image

Attaches an image to a card already uploaded to the session. Cardloader sends a JPEG of about 1024 px on the long edge.

Attributes

  • Name
    event_id
    Type
    string
    Description

    The event_id of the card.

  • Name
    image
    Type
    string
    Description

    The image, Base64-encoded.

Returns

The identification row, with its id and image URL. 404 if the session has no card with this event_id.

Request

POST
/cards-cloud/v2/session/{id}/images/
curl --location 'https://api.ximilar.com/cards-cloud/v2/session/__SESSION_ID__/images/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token __API_TOKEN__' \
--data '{
  "event_id": "3f9a1c0e7b2d4e58",
  "image": "__BASE64_JPEG__"
}'

GET/cards-cloud/v2/identification/

List a session's cards

Lists the cards of a session, a page at a time.

Required attributes

  • Name
    session
    Type
    string
    Description

    ID of the session.

Optional attributes

  • Name
    event_id
    Type
    string
    Description

    Only the card with this event_id.

  • Name
    page
    Type
    integer
    Default
    Default:1
    Description

    Page number.

  • Name
    page_size
    Type
    integer
    Max
    Maximum:500
    Description

    Cards per page.

Returns

count, next (URL of the next page, or null) and results, a list of identifications.

Request

GET
/cards-cloud/v2/identification/
curl -H 'Authorization: Token __API_TOKEN__' \
     'https://api.ximilar.com/cards-cloud/v2/identification/?session=__SESSION_ID__&page=1&page_size=100'

Response

{
  "count": 18,
  "next": "https://api.ximilar.com/cards-cloud/v2/identification/?page=2&page_size=100&session=__SESSION_ID__",
  "results": [
    {
      "id": "c41d7e22-90b3-4f6a-8d15-2b7a9e0f3c88",
      "event_id": "3f9a1c0e7b2d4e58",
      "seen": "2026-10-14T16:21:03.120Z",
      "id_type": "tcg",
      "name": "Charizard ex",
      "full_name": "Charizard ex Obsidian Flames (OBF) #125",
      "set_name": "Obsidian Flames",
      "set_code": "OBF",
      "card_number": "125",
      "series": "Scarlet & Violet",
      "year": "2023",
      "subcategory": "Pokemon",
      "distance": 0.21,
      "confidence": "high",
      "links": {"tcgplayer.com": "https://example.com/product/125"},
      "alternatives": [],
      "price_stats": [{"stats_type": "ungraded", "value": {"median": 12.5}}],
      "price": 12.5,
      "image": "https://example.com/cards-cloud/c41d7e22.jpg",
      "thumbnail": "https://example.com/cards-cloud/c41d7e22_thumb.jpg",
      "grading": {"endpoint": "grade", "grades": {"final": 7.5, "condition": "Near Mint"}},
      "grade": 7.5,
      "sold": false,
      "note": ""
    }
  ]
}

PATCH/cards-cloud/v2/identification/{id}/

Correct a card's match

Replaces a card's match, for example when a user picks one of the alternatives instead of the best match. Cards Cloud keeps it as the user's correction. Works on live and closed sessions.

Find the row's id in the answer to Upload a card's image, or with List a session's cards filtered by event_id.

Attributes

  • Name
    name
    Type
    string
    Max
    Maximum:255
    Description

    Card name.

  • Name
    full_name
    Type
    string
    Max
    Maximum:500
    Description

    Full card name.

  • Name
    set_name
    Type
    string
    Max
    Maximum:255
    Description

    Set.

  • Name
    set_code
    Type
    string
    Max
    Maximum:50
    Description

    Set code.

  • Name
    card_number
    Type
    string
    Max
    Maximum:50
    Description

    Card number.

  • Name
    series
    Type
    string
    Max
    Maximum:255
    Description

    Series.

  • Name
    year
    Type
    string
    Max
    Maximum:20
    Description

    Year.

  • Name
    subcategory
    Type
    string
    Max
    Maximum:100
    Description

    Game or sport.

  • Name
    price
    Type
    number
    Description

    Price of the picked card (USD), or null.

Returns

The updated identification, or 404 if the row was deleted.

Request

PATCH
/cards-cloud/v2/identification/{id}/
curl -XPATCH 'https://api.ximilar.com/cards-cloud/v2/identification/__ID__/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token __API_TOKEN__' \
--data '{
  "name": "Charizard ex",
  "full_name": "Charizard ex Obsidian Flames (OBF) #223",
  "set_name": "Obsidian Flames",
  "set_code": "OBF",
  "card_number": "223",
  "series": "Scarlet & Violet",
  "year": "2023",
  "subcategory": "Pokemon",
  "price": 80.0
}'

Errors

Cards Cloud answers with the usual HTTP status codes. The ones a client should handle:

StatusMeaning
401Missing or invalid API token.
402Not enough credits (for example, to create a session).
403Cards Cloud isn't enabled for the account.
404The session or row doesn't exist (it may have been deleted).
409Conflict.
429Too many requests — retry later.
5xxServer error — retry later.

Was this page helpful?