Skip to content
Beta Release: JK Index is in active development. Data coverage is expanding and you may see gaps or inconsistencies as we iterate. Feedback is welcome.

Private known-card beta · USD only

JK Index Pricing API v0 consumer documentation

This is the integration source of truth for all four supported V0 routes. It covers resolution, ambiguity selection, price snapshots, batch, history, caching, authentication, quotas, and errors.

API Basehttps://api.jkindex.io
Status

If you see 404 on /api/v0/*, you're likely calling jkindex.io instead of api.jkindex.io.

1. Base URL and authentication

Send every request to https://api.jkindex.io. The website host does not serve the API. Every supported V0 route requires a hand-issued, per-consumer bearer key:

Authorization: Bearer YOUR_API_KEY
  • Never put a key in a query string, browser URL, repository, or support message.
  • A revoked, inactive, missing, or invalid key returns the same stable 401 body.
  • Keys and both quotas are per consumer. The exact per-minute and rolling-30-day limits are communicated at issuance.
  • Every response carries X-Request-Id. Include it with the UTC timestamp when reporting an issue.

2. First known-card request

V0 is structured resolution, not search. Start with a TCG identifier, set identifier, and collector number that you already hold.

curl --get \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --data-urlencode "tcg=pokemon" \
  --data-urlencode "set=jungle" \
  --data-urlencode "number=64" \
  --data-urlencode "segment=raw_nm" \
  --data-urlencode "currency=usd" \
  "https://api.jkindex.io/api/v0/price"
{
  "outcome": "matched",
  "canonical_id": "jungle-064-pikachu-1st",
  "identity": {
    "tcg": "pokemon",
    "set_slug": "jungle",
    "set_code": "JNG",
    "number_norm": "64",
    "number_display": "64",
    "variant": "1st",
    "language": "en",
    "set_alias": null,
    "matched_set_alias": null
  },
  "image_url": "https://cdn.jkindex.io/cards/jungle/64-1st.webp",
  "image_url_absolute": "https://cdn.jkindex.io/cards/jungle/64-1st.webp",
  "display_name": "Pikachu",
  "edition": "1st",
  "match": {
    "status": "exact",
    "confidence": "exact",
    "reason_codes": [
      "set_slug_exact",
      "collector_number_exact"
    ]
  },
  "confidence": "exact",
  "candidate_ref": "c1_<opaque-reference-from-response>",
  "other_printings": [],
  "pricing": {
    "segment": "raw_nm",
    "as_of": "2026-07-30T18:00:00Z",
    "snapshot": {
      "latest": "30.00",
      "median": "20.00",
      "count": 3,
      "currency": "USD"
    },
    "freshness": {
      "state": "fresh",
      "age_days": 1,
      "fresh_max_age_days": 7,
      "stale_after_days": 21
    },
    "segment_basis": "strict_segment",
    "reason_code": null
  }
}

Money is serialized as fixed-decimal strings. canonical_id is a stable identity value, not a selection protocol.

3. Understand matched, ambiguous, and not-found outcomes

OutcomeMeaningNext action
matchedExactly one printing resolved.Read identity and the segment-scoped pricing block.
ambiguousSeveral active printings match.Choose a candidate and copy its candidate_ref verbatim.
not_foundThe reference or requested contract dimension failed closed.Branch on the top-level reason_code; do not infer catalog-wide absence.

These are domain answers over HTTP 200. Only a matched response has match, categorical confidence, and pricing. Ambiguous and not-found outcomes do not carry a top-level confidence value.

{
  "outcome": "ambiguous",
  "candidates": [
    {
      "canonical_id": "jungle-054-jigglypuff-1st",
      "identity": {
        "tcg": "pokemon",
        "set_slug": "jungle",
        "set_code": "JNG",
        "number_norm": "54",
        "number_display": "54",
        "variant": "1st",
        "language": "en",
        "set_alias": null,
        "matched_set_alias": null
      },
      "image_url": null,
      "display_name": "Jigglypuff",
      "edition": "1st",
      "variant": "1st",
      "candidate_ref": "c1_<first-opaque-reference>",
      "variant_is_unique": false,
      "image_url_absolute": null
    },
    {
      "canonical_id": "jungle-054-jigglypuff-unlimited",
      "identity": {
        "tcg": "pokemon",
        "set_slug": "jungle",
        "set_code": "JNG",
        "number_norm": "54",
        "number_display": "54",
        "variant": "unlimited",
        "language": "en",
        "set_alias": null,
        "matched_set_alias": null
      },
      "image_url": null,
      "display_name": "Jigglypuff",
      "edition": "unlimited",
      "variant": "unlimited",
      "candidate_ref": "c1_<second-opaque-reference>",
      "variant_is_unique": true,
      "image_url_absolute": null
    }
  ]
}
{
  "outcome": "not_found",
  "reason_code": "unknown_candidate_ref",
  "message": "unknown_candidate_ref"
}

4. Select an ambiguous printing with candidate_ref

  1. Render candidate identity, display name, edition, variant, and image as provided.
  2. Keep the selected candidate's opaque candidate_ref unchanged.
  3. Repeat price or history with that value. Do not parse or construct a reference.
CANDIDATE_REF='PASTE_CANDIDATE_REF_VALUE_VERBATIM'
curl --get \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --data-urlencode "tcg=pokemon" \
  --data-urlencode "set=jungle" \
  --data-urlencode "number=54" \
  --data-urlencode "candidate_ref=${CANDIDATE_REF}" \
  --data-urlencode "segment=raw_nm" \
  "https://api.jkindex.io/api/v0/price"
{
  "outcome": "matched",
  "canonical_id": "jungle-054-jigglypuff-unlimited",
  "identity": {
    "tcg": "pokemon",
    "set_slug": "jungle",
    "set_code": "JNG",
    "number_norm": "54",
    "number_display": "54",
    "variant": "unlimited",
    "language": "en",
    "set_alias": null,
    "matched_set_alias": null
  },
  "image_url": null,
  "image_url_absolute": null,
  "display_name": "Jigglypuff",
  "edition": "unlimited",
  "match": {
    "status": "exact",
    "confidence": "exact",
    "reason_codes": [
      "set_slug_exact",
      "candidate_ref_match"
    ]
  },
  "confidence": "exact",
  "candidate_ref": "c1_<second-opaque-reference>",
  "other_printings": [],
  "pricing": {
    "segment": "raw_nm",
    "as_of": "2026-07-30T18:00:00Z",
    "snapshot": {
      "latest": "30.00",
      "median": "20.00",
      "count": 3,
      "currency": "USD"
    },
    "freshness": {
      "state": "fresh",
      "age_days": 1,
      "fresh_max_age_days": 7,
      "stale_after_days": 21
    },
    "segment_basis": "strict_segment",
    "reason_code": null
  }
}

A recognized reference selects exactly one active card in the supplied TCG and set. Empty whitespace is treated as no reference. Every other supplied value— malformed, stale after catalog changes, or unknown—returns unknown_candidate_ref and never falls back to number matching. Candidate refs have no published expiration time.

variant remains exact-after-trim and case-sensitive. It can help, but candidates with variant_is_unique: false prove that a variant is not always sufficient; candidate_ref is the reliable path.

5. GET /api/v0/price

ParameterRequiredContract
tcgyespokemon or one-piece; case-insensitive.
setyesSet slug, set code, or registered alias; case-insensitive.
numberyesStructured collector number; normalization is listed below.
variantnoExact-after-trim, case-sensitive printing discriminator.
languagenoDefaults to en; accepted and echoed, not an enforced catalog filter.
segmentnoRequired for non-null pricing; one of the seven supported segments.
currencynoDefaults to usd; USD is the only supported currency.
candidate_refnoOpaque selector copied verbatim from a prior candidate or match.

Supported number forms

Numeric (54, 054), optional hash (#54), fraction (54/102), alpha suffix (54a), subset code (TG12), and alphanumeric prefixed forms (OP01-121) are supported. Prefix matching is set-scoped; the resolver never guesses across sets.

Verified One Piece forms include set alias OP01 withOP01-121 or bare 121, case-insensitiveop01-001, and set OP07 with eitherOP07-119 or bare 119. The OP01-121 production shape is legitimately ambiguous and returns candidate refs.

curl --get \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --data-urlencode "tcg=one-piece" \
  --data-urlencode "set=OP01" \
  --data-urlencode "number=OP01-121" \
  "https://api.jkindex.io/api/v0/price"

# The verified bare-number equivalent uses set=OP01 and number=121.

Pricing-null cases

  • No segment: matched identity with pricing.reason_code: pricing_requires_segment.
  • Supported segment with no qualifying sale: matched identity with pricing.reason_code: no_pricing_for_segment.
  • Unsupported segment: top-level not-found unsupported_segment plus supported_segments.
  • Non-USD: top-level not-found unsupported_currency plus supported_currencies: ["USD"].
{
  "outcome": "matched",
  "canonical_id": "jungle-064-pikachu-1st",
  "identity": {
    "tcg": "pokemon",
    "set_slug": "jungle",
    "set_code": "JNG",
    "number_norm": "64",
    "number_display": "64",
    "variant": "1st",
    "language": "en",
    "set_alias": null,
    "matched_set_alias": null
  },
  "image_url": "https://cdn.jkindex.io/cards/jungle/64-1st.webp",
  "image_url_absolute": "https://cdn.jkindex.io/cards/jungle/64-1st.webp",
  "display_name": "Pikachu",
  "edition": "1st",
  "match": {
    "status": "exact",
    "confidence": "exact",
    "reason_codes": [
      "set_slug_exact",
      "collector_number_exact"
    ]
  },
  "confidence": "exact",
  "candidate_ref": "c1_<opaque-reference-from-response>",
  "other_printings": [],
  "pricing": {
    "segment": "psa_10",
    "snapshot": null,
    "reason_code": "no_pricing_for_segment"
  }
}

6. POST /api/v0/price/batch

Batch is live. Send references with 1–50 items. Each item accepts the same dimensions as price plus optional request_id(maximum 128 characters, echoed) and per-item candidate_ref.

  • Input order and count are preserved; results carry zero-based index.
  • Each item resolves independently. A domain-invalid item is a per-item outcome; it does not fail valid siblings.
  • A structurally invalid body or item fails the whole request with 422.
  • More than 50 references fails with 400 batch_too_large before lookup.
  • Quota cost is N references, reserved all-or-nothing before resolution. A refused batch consumes nothing.
  • Identical references are resolved once and fanned out; each item still appears in its original position.
{
  "references": [
    {
      "request_id": "direct-match",
      "tcg": "pokemon",
      "set": "jungle",
      "number": "64",
      "segment": "raw_nm",
      "currency": "usd"
    },
    {
      "request_id": "needs-selection",
      "tcg": "pokemon",
      "set": "jungle",
      "number": "54"
    },
    {
      "request_id": "bad-reference",
      "tcg": "pokemon",
      "set": "jungle",
      "number": "54",
      "candidate_ref": "c1_<unknown-opaque-reference>"
    }
  ]
}
{
  "outcome": "batch",
  "count": 3,
  "generated_at": "2026-07-31T18:00:00Z",
  "results": [
    {
      "index": 0,
      "request_id": "direct-match",
      "etag": "\"0123456789abcdef\"",
      "outcome": "matched",
      "canonical_id": "jungle-064-pikachu-1st",
      "identity": {
        "tcg": "pokemon",
        "set_slug": "jungle",
        "set_code": "JNG",
        "number_norm": "64",
        "number_display": "64",
        "variant": "1st",
        "language": "en",
        "set_alias": null,
        "matched_set_alias": null
      },
      "image_url": "https://cdn.jkindex.io/cards/jungle/64-1st.webp",
      "image_url_absolute": "https://cdn.jkindex.io/cards/jungle/64-1st.webp",
      "display_name": "Pikachu",
      "edition": "1st",
      "match": {
        "status": "exact",
        "confidence": "exact",
        "reason_codes": [
          "set_slug_exact",
          "collector_number_exact"
        ]
      },
      "confidence": "exact",
      "candidate_ref": "c1_<opaque-reference-from-response>",
      "other_printings": [],
      "pricing": {
        "segment": "raw_nm",
        "as_of": "2026-07-30T18:00:00Z",
        "snapshot": {
          "latest": "30.00",
          "median": "20.00",
          "count": 3,
          "currency": "USD"
        },
        "freshness": {
          "state": "fresh",
          "age_days": 1,
          "fresh_max_age_days": 7,
          "stale_after_days": 21
        },
        "segment_basis": "strict_segment",
        "reason_code": null
      }
    },
    {
      "index": 1,
      "request_id": "needs-selection",
      "etag": "\"123456789abcdef0\"",
      "outcome": "ambiguous",
      "candidates": [
        {
          "canonical_id": "jungle-054-jigglypuff-1st",
          "identity": {
            "tcg": "pokemon",
            "set_slug": "jungle",
            "set_code": "JNG",
            "number_norm": "54",
            "number_display": "54",
            "variant": "1st",
            "language": "en",
            "set_alias": null,
            "matched_set_alias": null
          },
          "image_url": null,
          "display_name": "Jigglypuff",
          "edition": "1st",
          "variant": "1st",
          "candidate_ref": "c1_<first-opaque-reference>",
          "variant_is_unique": false,
          "image_url_absolute": null
        },
        {
          "canonical_id": "jungle-054-jigglypuff-unlimited",
          "identity": {
            "tcg": "pokemon",
            "set_slug": "jungle",
            "set_code": "JNG",
            "number_norm": "54",
            "number_display": "54",
            "variant": "unlimited",
            "language": "en",
            "set_alias": null,
            "matched_set_alias": null
          },
          "image_url": null,
          "display_name": "Jigglypuff",
          "edition": "unlimited",
          "variant": "unlimited",
          "candidate_ref": "c1_<second-opaque-reference>",
          "variant_is_unique": true,
          "image_url_absolute": null
        }
      ]
    },
    {
      "index": 2,
      "request_id": "bad-reference",
      "etag": "\"23456789abcdef01\"",
      "outcome": "not_found",
      "reason_code": "unknown_candidate_ref",
      "message": "unknown_candidate_ref"
    }
  ]
}

Each result is a normal price outcome plus index,request_id, and its quoted etag. The batch-levelgenerated_at is assembly time; price time remainspricing.as_of per item.

7. GET /api/v0/price/history

History returns derived aggregates, never raw sale rows. Identity must resolve to one card and segment is required.

ParameterRequired/defaultContract
tcg, set, numberrequiredSame resolution rules as price.
segmentrequiredOne supported raw or PSA segment.
currencyusdUSD only.
variant, language, candidate_refoptionalSame identity semantics as price.
startend minus 90 daysInclusive ISO date.
endtodayInclusive ISO date; future input clamps to today.
intervalweekday, week, month.
limit4001–400 points.
cursoroptionalExclusive: return buckets after this prior interval_start.

The inclusive range may span at most 366 days. Points are ascending. Missing intervals are omitted, not zero-filled or forward-filled. An empty series returns points: [], point_count: 0,series_freshness: null, and next_cursor: null.

An ambiguous history reference returns the candidates plus message: history_requires_unambiguous_reference. Copy a candidate ref into the same history request to obtain the series.

curl --get \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --data-urlencode "tcg=pokemon" \
  --data-urlencode "set=jungle" \
  --data-urlencode "number=64" \
  --data-urlencode "segment=raw_nm" \
  --data-urlencode "start=2026-06-01" \
  --data-urlencode "end=2026-07-31" \
  --data-urlencode "interval=week" \
  --data-urlencode "limit=2" \
  "https://api.jkindex.io/api/v0/price/history"
{
  "outcome": "history",
  "canonical_id": "jungle-064-pikachu-1st",
  "identity": {
    "tcg": "pokemon",
    "set_slug": "jungle",
    "set_code": "JNG",
    "number_norm": "64",
    "number_display": "64",
    "variant": "1st",
    "language": "en",
    "set_alias": null,
    "matched_set_alias": null
  },
  "segment": "raw_nm",
  "currency": "USD",
  "interval": "week",
  "start": "2026-06-01",
  "end": "2026-07-31",
  "points": [
    {
      "interval_start": "2026-07-06",
      "median": "20.00",
      "latest": "30.00",
      "observation_count": 3
    },
    {
      "interval_start": "2026-07-13",
      "median": "22.00",
      "latest": "24.00",
      "observation_count": 2
    }
  ],
  "point_count": 2,
  "missing_intervals_policy": "omitted",
  "series_freshness": {
    "state": "fresh",
    "age_days": 1,
    "fresh_max_age_days": 7,
    "stale_after_days": 21,
    "last_sale_at": "2026-07-30T18:00:00Z"
  },
  "next_cursor": "2026-07-13",
  "retention": "full_source_history"
}
curl --get \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --data-urlencode "tcg=pokemon" \
  --data-urlencode "set=jungle" \
  --data-urlencode "number=64" \
  --data-urlencode "segment=raw_nm" \
  --data-urlencode "start=2026-06-01" \
  --data-urlencode "end=2026-07-31" \
  --data-urlencode "interval=week" \
  --data-urlencode "limit=2" \
  --data-urlencode "cursor=2026-07-13" \
  "https://api.jkindex.io/api/v0/price/history"
{
  "outcome": "history",
  "canonical_id": "jungle-064-pikachu-1st",
  "identity": {
    "tcg": "pokemon",
    "set_slug": "jungle",
    "set_code": "JNG",
    "number_norm": "64",
    "number_display": "64",
    "variant": "1st",
    "language": "en",
    "set_alias": null,
    "matched_set_alias": null
  },
  "segment": "raw_nm",
  "currency": "USD",
  "interval": "week",
  "start": "2026-06-01",
  "end": "2026-07-31",
  "points": [
    {
      "interval_start": "2026-07-20",
      "median": "25.00",
      "latest": "27.00",
      "observation_count": 2
    }
  ],
  "point_count": 1,
  "missing_intervals_policy": "omitted",
  "series_freshness": {
    "state": "fresh",
    "age_days": 1,
    "fresh_max_age_days": 7,
    "stale_after_days": 21,
    "last_sale_at": "2026-07-30T18:00:00Z"
  },
  "next_cursor": null,
  "retention": "full_source_history"
}

8. Handle freshness, unavailable pricing, and images

A priced response carries as_of, a snapshot, andfreshness with state, age_days,fresh_max_age_days, and stale_after_days.fresh is at or below the first threshold,aging is between thresholds, and stale is older. Stale pricing remains served and is labeled; it is never presented as current.

{
  "outcome": "matched",
  "canonical_id": "jungle-064-pikachu-1st",
  "identity": {
    "tcg": "pokemon",
    "set_slug": "jungle",
    "set_code": "JNG",
    "number_norm": "64",
    "number_display": "64",
    "variant": "1st",
    "language": "en",
    "set_alias": null,
    "matched_set_alias": null
  },
  "image_url": "https://cdn.jkindex.io/cards/jungle/64-1st.webp",
  "image_url_absolute": "https://cdn.jkindex.io/cards/jungle/64-1st.webp",
  "display_name": "Pikachu",
  "edition": "1st",
  "match": {
    "status": "exact",
    "confidence": "exact",
    "reason_codes": [
      "set_slug_exact",
      "collector_number_exact"
    ]
  },
  "confidence": "exact",
  "candidate_ref": "c1_<opaque-reference-from-response>",
  "other_printings": [],
  "pricing": {
    "segment": "raw_nm",
    "as_of": "2026-05-31T18:00:00Z",
    "snapshot": {
      "latest": "30.00",
      "median": "20.00",
      "count": 3,
      "currency": "USD"
    },
    "freshness": {
      "state": "stale",
      "age_days": 61,
      "fresh_max_age_days": 7,
      "stale_after_days": 21
    },
    "segment_basis": "strict_segment",
    "reason_code": null
  }
}

No qualifying observation is different from stale data: no_pricing_for_segment has a null snapshot and noas_of or freshness. History freshness describes the newest sale across the whole requested series, not only the current page.

image_url is the stored value and may be null.image_url_absolute passes an absolute URL through, joins a configured asset base only for supported relative paths, and otherwise remains null. Render these values as returned; never invent a card-image host or path.

9. Cache with ETag and conditional 304

RouteCache-ControlIf-None-Match
GET /api/v0/pricepublic, max-age=300304 supported
POST /api/v0/price/batchpublic, max-age=300304 supported
GET /api/v0/price/historypublic, max-age=900304 supported
GET /api/v0/healthprivate, max-age=30Not supported; always 200 when authenticated

ETags are quoted opaque values. Cache keys must include every request dimension, including TCG, set form, number form, variant, language, segment, currency, candidate ref, and history page dimensions. Never construct or parse an ETag.

curl --get \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H 'If-None-Match: "0123456789abcdef"' \
  --data-urlencode "tcg=pokemon" \
  --data-urlencode "set=jungle" \
  --data-urlencode "number=64" \
  --data-urlencode "segment=raw_nm" \
  "https://api.jkindex.io/api/v0/price"

# Unchanged representation:
HTTP/1.1 304 Not Modified
ETag: "0123456789abcdef"
Cache-Control: public, max-age=300
X-Request-Id: 12345678-1234-1234-1234-123456789abc

10. Handle errors, retries, and rate limits

HTTPMeaningRetry
200Domain envelope: matched, ambiguous, not_found, batch, history, or health.Branch on the body; do not retry a deterministic reason unchanged.
304Cached price, batch, or history representation is current; empty body.Use the cached body.
400Batch exceeds 50 items.Split the batch.
401Missing, invalid, inactive, or revoked key.Stop and correct credentials; do not loop.
422FastAPI request validation failed.Correct the request shape.
429Per-minute or rolling-30-day per-key limit refused the request.Honor Retry-After; refused work consumes nothing.
5xxUnexpected service failure.Bounded exponential backoff with jitter; include request ID if persistent.

The supported V0 application does not emit an application-level 403. A 403 from an upstream edge or unusual client is outside the JSON contract; record the body, headers, client, UTC timestamp, and request ID rather than treating it as a bad key.

Stable public headers are X-Request-Id on every response,ETag and Cache-Control on successful domain responses, and Retry-After on 429. There are no promisedX-RateLimit-Remaining headers.

{
  "error": "unauthorized",
  "message": "Missing or invalid API key"
}
{
  "detail": [
    {
      "type": "missing",
      "loc": [
        "query",
        "tcg"
      ],
      "msg": "Field required",
      "input": null
    }
  ]
}
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-Request-Id: 12345678-1234-1234-1234-123456789abc

{
  "error": "rate_limited",
  "message": "Too many requests"
}

GET /api/v0/health

This route requires the same bearer key and does not consume the pricing rate limit. It always returns HTTP 200 after authentication with status, UTC time, deployed version, and checks.

{
  "status": "ok",
  "time": "2026-07-31T18:00:00Z",
  "version": "0123456789ab",
  "checks": {
    "db": "ok",
    "fx_table": "ok",
    "fx_rate_usd_cad": "ok"
  }
}

checks.db is relevant to request serviceability. Thefx_table and fx_rate_usd_cad entries are operator diagnostics retained in the health envelope; they do not enable or imply consumer currency conversion. USD remains the only supported currency.

The public website status page calls unauthenticated readiness and checks route presence. It is not the keyed health response and does not spend your key quota.

Shared contract reference

Supported identifiers, segments, and currency

  • Verified TCG identifiers: pokemon, one-piece.
  • Segments: raw_nmraw_lpraw_mppsa_7psa_8psa_9psa_10
  • Only usd requests are supported; responses serialize currency: "USD".
  • CGC, BGS, aggregate raw, and aggregate graded are unsupported.

Top-level reason codes

ReasonMeaning / action
unsupported_tcgUse a verified TCG identifier.
unsupported_setThe set slug, code, or alias did not resolve for this TCG.
invalid_number_formatThe number was empty or structurally invalid.
unsupported_number_formatUse a supported structured number form.
card_not_in_setNo active card matched that set-scoped number.
card_identity_unresolvedCatalog rows exist but no addressable number identity is available; report data quality.
variant_not_foundThe supplied case-sensitive variant matched no candidate.
unknown_candidate_refObtain a fresh candidate list; never fall back silently.
unsupported_segmentUse one of supported_segments.
unsupported_currencyUse USD.
invalid_intervalHistory interval must be day, week, or month.
invalid_date_rangeHistory start must not be after end.
date_range_too_largeReduce history to at most 366 days.

Null-pricing reason codes are separate: pricing_requires_segment and no_pricing_for_segment. Batch has the transport-level 400 reason batch_too_large.

Confidence and contract versioning

Match confidence is categorical, never a probability. exact means stored values matched directly; high means a documented, deterministic normalization fired. The top-level value equalsmatch.confidence. Clients must tolerate additive optional fields and reason codes. Breaking changes require a new API version or a communicated deprecation.

Coverage and catalog discovery are excluded

GET /api/v0/coverage is not registered, is absent from public OpenAPI, and returns the standard 404 {"detail":"Not Found"}. The beta does not enumerate every supported set or card and does not promise an exact live coverage summary. Consumers provide known identifiers. A per-request not_found or no_pricing_for_segmentresult must not be generalized to the catalog.

Current changelog

  • 2026-07-31 — Consumer documentation parity. All four live routes, exact response schemas, bearer security, batch/history workflows, caching, errors, and public examples aligned with runtime.
  • 2026-07-31 — Controlled beta without discovery. USD known-card resolution and pricing remain supported; coverage and catalog enumeration are excluded.
  • 2026-07-29 — USD beta closure. Non-USD fails closed; candidate refs complete ambiguity selection; unknown refs do not fall back; matched results disclose other printings.
  • 2026-07-28 — Consumer-readiness additions. One Piece prefixed/bare-number corrections, variant detail, confidence correction, truthful image URL handling, freshness labels, ETag/304, batch, history, authentication, and quota hardening.

Support checklist

Report the exact request without its key, full response, UTC timestamp, X-Request-Id, and ETag. Load, soak, stress, or high-concurrency testing requires prior written authorization with an explicit request budget, concurrency cap, time window, and stop conditions.

JK Index was created under Riot Games' "Legal Jibber Jabber" policy using assets owned by Riot Games. Riot Games does not endorse or sponsor this project.

JK Index isn't endorsed by Riot Games and doesn't reflect the views or opinions of Riot Games or anyone officially involved in producing or managing Riot Games properties. Riot Games, and all associated properties are trademarks or registered trademarks of Riot Games, Inc.

JK Index is an independent collection and price-tracking platform. Riftbound card images and market data shown on this site come from JK Index’s own independent data sources, not from Riot Games or a Riot API.

Riot Games legal policies