Throttling
CarJam limits how fast a Development Connection may call the APIs, so that one busy integration cannot slow the register lookups down for everyone else. The limit is generous for ordinary use; you will only meet it when you fire requests in tight parallel loops or replay a backlog without pausing.
The limit
30 requests in any 10 second window, per Development Connection.
- The window is rolling: at the moment a request arrives we count the requests you made in the previous 10 seconds. If that count has reached 30, the request is throttled. On
/api/car/the request being checked is already in that count, so keep to fewer than 30 in any 10 seconds to be safe. - The count is per Development Connection (per member), not per API key. Every API key you generate under the same connection shares the one allowance.
- On
/api/car/every request that reaches your API usage log counts, including one answered from our cache and one that ended in an error. A request rejected before it is logged, for a missing or invalid API key, an invalid plate, or no products asked for, does not count. - On the
/a/vehicleAPIs a request counts once it is answered with data and charged. Anull"still fetching" response and a repeat of the same plate within the hour, which is not charged, do not count. - The same limit applies on the test environment, so a load test against test behaves the way production will.
A steady rate below 3 requests a second never trips it. Bursts above that are fine as long as they stay under 30 in any 10 seconds.
What a throttled request looks like
The APIs answer a throttled request in one of two ways, depending on the API.
Vehicle queries (/api/car/)
The throttle is checked when a request needs to go to the register: a basic lookup that is not in our cache, and every owners, owner, rucs and ppsr request. A basic-only request answered from cache is not throttled.
A throttled request is answered with an error response, with the scode of err-too-many-requests. Nothing is fetched and nothing is charged for it. The HTTP status is 200, as with every other API error, so look at the top-level tag rather than the status code.
<error>
<code>-1</code>
<scode>err-too-many-requests</scode>
<message>Too many requests.</message>
<class>apperror</class>
</error>
{
"code": -1,
"scode": "err-too-many-requests",
"message": "Too many requests.",
"class": "apperror"
}
Wait 2 seconds and send the same request again.
ABCD, Extra vehicle info, Japan Lookup and Member reports (/a/...)
These APIs, and the member reports lookup at /a/member:reports, already answer null with a Refresh: <seconds> HTTP header while data is being fetched (see ABCD for the pattern). A throttled request is answered the same way: the body is null, the Refresh header tells you how many seconds to wait, at least 2, and the X-Refresh-Notices header says why:
HTTP/1.1 200 OK
Content-Type: application/json
Refresh: 2.000000
X-Refresh-Notices: {"info":["Too many requests."]}
null
Nothing is charged for a null response. Wait the number of seconds the header names and repeat the request; the poll loop you already have for a null response handles this without any change.
The other APIs
At present only the APIs above are throttled. Please treat the limit as the guide for the others too; we may extend it to them without notice.
Handling it
- Read the response, not just the status code. A throttled request is an HTTP
200in both shapes above. Treaterr-too-many-requestsand anullbody with aRefreshheader as "try again shortly", not as a failure of the lookup. - Retry with a pause. Wait at least the
Refreshvalue (or 2 seconds for/api/car/) before retrying, and back off further if you are throttled again. Retrying immediately keeps you over the limit, and on/api/car/every retry is logged and counts against the window too. - Pace bulk work. When you process a list of plates, keep a single worker below 3 requests a second, or space parallel workers so their combined rate stays under 30 requests in any 10 seconds. For large batches, Batch Reports processes a whole list for you without any pacing on your side.
- Ask for what you need in one request. On
/api/car/,basic=1&owners=1&ppsr=1is one request against the limit; the same data as three separate calls is three.
Throttling is separate from the null / Refresh answer you get while the register is being read. That one means the data is on its way; this one means you are asking too fast. Both are handled by the same wait-and-retry loop.
If your integration genuinely needs a higher rate, please contact us and tell us about your use case.