Building on the API
The API is free, open and shared by every caller. A few habits keep it that way.
Fetch in bulk, not per row
Section titled “Fetch in bulk, not per row”A page with many listings (a marketplace overlay, a search index) should
fetch once per item via GET /v1/items/{def}/{paint}/patterns, then look up
each seed locally — never one /seeds/{seed} call per row. For a full local
copy, use /v1/dump once instead of
crawling every item.
Respect the cache
Section titled “Respect the cache”- Send
If-None-Matchand handle304— see Caching & conditional requests. - Responses are cached at the Cloudflare edge for 10 minutes; polling more often than that just re-reads the same cached response, at your own request budget’s expense.
dataset_versionchanges only when the data or the way responses are derived from it changes, not on docs or infrastructure deploys. A poller that checksGET /v1/metafirst and re-fetches only on a new version does very little work most of the time.
A sane polling cadence
Section titled “A sane polling cadence”| you’re building… | check | cadence |
|---|---|---|
| a live overlay reacting to new guides | GET /v1/meta, compare dataset_version |
every few minutes, not every second |
| a nightly mirror or search index | GET /v1/dump with If-None-Match |
once a day |
| a single page load | whatever endpoint fits the page | once, on load |
Respect the rate limit
Section titled “Respect the rate limit”1000 requests per minute per IP, enforced by the app; a 429 carries
Retry-After — wait at least that long before retrying. Cloudflare
separately caps bursts at 170 requests per 10 seconds per IP, blocking for
10 seconds past it, so spread requests out rather than firing them all at
once. In a browser that block shows up as a network error, not a 429:
back off and retry the same way. See
Access & rate limits.
Attribute every grade you show
Section titled “Attribute every grade you show”Not a performance concern, but non-negotiable: see Attribution.