Stay inside the plan
Most quota is spent re-asking for data that has not changed. What each plan allows, which calls are free, and which shapes replace five requests.
What a day allows
Daily ceilings, per key, from the configuration the middleware enforces. Rate limits covers the per-minute side.
| Plan | Requests / day | MCP calls / day | Pages deep |
|---|---|---|---|
| Explorer | 50 | 20 | 5 |
| Builder | 2,000 | 500 | 25 |
| Studio | 10,000 | 2,500 | No ceiling |
| Enterprise | 50,000 | 10,000 | No ceiling |
MCP calls are a sub-cap inside the request cap, never an extra allowance: whichever is reached first refuses the call, which the MCP limits page explains. A burst of more than 10 pages in 90 seconds is also refused, so walk the catalog steadily rather than in parallel.
The calls that cost you nothing
Two of them, and together they are usually the difference between a plan that fits and one that does not.
- A
304 Not Modifiedis not counted against your daily cap. Revalidating what you already hold is free; re-downloading it is not. Caching has the mechanics. - A response served from your own cache never reaches us at all. Respect the
Cache-Controlwe send and a busy page collapses to one upstream call per lifetime. - A webhook delivery is not a request of yours either, since we are calling you. Taking changes as deltas rather than polling for them therefore costs nothing per record, which is what mirroring the catalog is built on.
Ask for more in fewer calls
The same page, the same data, a quarter of the requests. These endpoints exist because the loop that replaces them is the one everybody writes first.
// Four calls, one page render.const g17 = await gunspec.firearms.get('glock-g17')const p226 = await gunspec.firearms.get('sig-sauer-p226')const m9 = await gunspec.firearms.get('beretta-92fs')const p320 = await gunspec.firearms.get('sig-sauer-p320') // One call, the same page, and the fields already lined up for a// table. Up to five ids, as one comma-separated string.const { data } = await gunspec.firearms.compare({ ids: 'glock-g17,sig-sauer-p226,beretta-92fs,sig-sauer-p320',})- Compare up to five records in one call rather than fetching each. The fields come back already lined up.
- Resolve up to fifty names in one call instead of one at a time, which the resolve guide covers.
- Ask for what you render with
fields, and raiseper_pagerather than making more pages: one page of a hundred costs one request, five pages of twenty cost five. - Prefer an endpoint that already answers your question (variants, similar, attachments) over reassembling it from a list plus a loop.
Watch the busiest key, not the average
Caps apply per key, and the API refuses one key at a time, so an account-wide average hides the key that is about to start failing. The usage endpoint reports both, and the same numbers are on your profile.
// What the account has actually spent, from the same counters// the caps are checked against.const { data } = await gunspec.usage.get() if (data.currentMonth.percentage > 80) { notify(`${data.currentMonth.used} of ${data.currentMonth.limit} requests used this month`)} // Watch the busiest key, never the account's sum: the API refuses one// key at a time, so an average hides the key about to start failing.const busiest = data.mcp?.busiestKeyTodayif (busiest && busiest.percentage > 80) { notify(`${busiest.keyName} is at ${busiest.percentage}% of today's MCP allowance`)}Optimise or upgrade
Both are legitimate. The signal tells you which one you are actually looking at.
| What you see | What it means |
|---|---|
| Many requests, few distinct records | Cache. You are re-asking for the same rows within their lifetime. |
| Bursts of 429 at the top of the hour | Spread the schedule and add jitter. Your cron is stampeding, not your traffic. |
| Steady growth in distinct records read | Upgrade. This is real demand and no amount of caching removes it. |
| PLAN_REQUIRED on one endpoint | Upgrade, or do without that endpoint. A new key on the same plan gets the same answer. |
| Depth limit hit while walking | Filter the walk into narrower slices, or move to a plan without a page ceiling. |