// RATE LIMITS

Per key, per minute.

Limits are attached to the key, not the IP. Each plan has a requests-per-minute ceiling and a monthly read quota; the sandbox has its own per-IP limit. A 429 always says when to come back.
60 req/min
on a free key.
10,000 reads / mo
included, free.
30 / min
per IP on the keyless sandbox.
Retry-After
on every 429, in seconds.

Limits by plan

PlanRequests / minuteReads / monthEnrichment
Free60 req/min10,000 reads / moNo enrich
Pro300 req/min250,000 reads / mo100 enrich runs / mo
Scale1,000 req/min2,000,000 reads / mo1,000 enrich runs / mo
EnterpriseCustomCustom quotaNegotiated credits

A read is one successful GET. Cache hits and enrichment status polls do not spend enrichment credits. Plan details and what each tier includes are on Access.

The headers to read

When the backend reports budget, the gateway passes X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and Retry-After through untouched. The sandbox always sends the first two. Read Retry-After on a 429 and sleep that many seconds; do not hammer.

429.http
curl -i 'https://vinspeclookup.com/api/v1/parts?config_key=2019_honda_cr_v_ex_l15be' \
-H 'Authorization: Bearer otp_live_…'
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
 
{ "error": "rate_limited", "message": "Limit is 60 requests/minute for this key." }
429 · back off for Retry-After seconds

The sandbox and the form

SurfaceLimitScope of the limit
https://vinspeclookup.com/api/sample30 requests / minutePer IP address. Read-only; writes return 403.
Request access form5 submissions / 10 minutesPer IP address. A 429 there carries Retry-After: 600.
POST /v0/enrich5 scheduled runs / day / keyThe spec's quota_exceeded example. Monthly credits are per plan above.

Designing around the limit

  • Pull the whole vehicle once. GET /v1/vehicle with include= is one read for every group you name; five group calls are five reads.
  • Cache by config_key. Specs, intervals and fitment do not change for a config. Prices carry as_of; refresh those on your own schedule.
  • Resolve identity once. Decode the VIN, keep the config_key, and use it for every later call. Ambiguous lookups are cheaper to settle with GET /v1/configs than to retry.

Backing off well

A 429 is a timing answer, not a failure. Read Retry-After, sleep that many seconds plus a little random jitter so a fleet of workers does not wake up together, then send the same request again. Cap the retries (three is plenty) and surface the last error code to your logs rather than looping.

On the keyless sandbox the limit is per IP address, so an office network or a CI runner shares one budget of 30 requests a minute. If your tests need more, run them against your own key, or replay the baked reference responses instead of calling out.

Bulk work belongs on the whole-vehicle call. Fetching five groups for a thousand vehicles is a thousand reads with include= and five thousand without it; the response shape is the same either way.