Core concepts
Rate limits
Limits are monthly and reset on the first of the month, UTC. Going over returns 429. It never returns a bill.
What each tier allows
| Tier | Requests per month | Price |
|---|---|---|
| Free | 2,000 general, up to 5,000 in total with /incidents/nearby | A$0 |
| Starter | 25,000 | A$9/mo |
| Developer | 80,000 | A$29/mo |
| Business | 200,000 | A$99/mo |
| Pro | 400,000 | A$299/mo |
| Organisation | 2,000,000 | A$3,588/yr |
| Enterprise | Custom | Custom |
The free tier's two allowances
A free key may make 2,000 requests a month to general endpoints, which is every endpoint except /api/v1/incidents/nearby. Calls to that one endpoint can take the month up to 5,000 in total. It is the endpoint the Home Assistant integration polls, so a home dashboard keeps working while bulk use of the national feed needs a paid plan.
Once the general allowance is used, general calls are refused and nearby calls carry on until the total is reached. The headers describe the call you made: on a nearby call, RateLimit-Limit is 5,000; on a general call it is the allowance that runs out first. The free tier is for evaluation, or personal and non-commercial use. Paid plans have one monthly limit across every endpoint.
There is no overage billing
When you reach your limit the API refuses further requests until the month rolls over or you upgrade. It does not keep serving and invoice you afterwards. That is a deliberate choice: a runaway loop in your code should cost you an outage you notice, not an invoice you find later.
Refused requests do not use up your allowance: limits are tested against the requests the API served. Your dashboard shows served requests, and counts refusals separately.
Hazard history lookups are counted separately and are not billed on either. Every account gets 100 a month, a block of 1,000 is A$99 a month in place of them, and the Organisation licence (A$3,588 a year) includes 1,000. At the limit the lookup is refused until the month rolls over. That refusal is a 403, not a 429: it carries no Retry-After, because waiting will not clear it. A lookup is any successful response, and a refused or invalid call never uses one.
Usage emails
On a paid plan, or with a custom monthly limit, we email the account holder when the month's usage reaches 50, 75 and 90 per cent of the limit. Usage is counted per account, across all its keys, and checked every hour. If it passes more than one mark between checks, you get one email for the highest. Every account, free included, gets one email when the limit is reached and requests start being refused. Each kind can be switched off in Settings, or with the link in the email.
The 429 contract
A rate-limited response carries the headers you need to back off without guessing. Read Retry-After and wait; do not retry on a fixed timer.
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
RateLimit-Limit: 5000
RateLimit-Remaining: 0
RateLimit-Reset: 1786924800
Retry-After: 1209600
{
"type": "https://dataquoll.io/errors/rate-limit-exceeded",
"title": "Rate Limit Exceeded",
"status": 429,
"detail": "You have exceeded your monthly limit of 5000 requests. Upgrade at https://dataquoll.io/pricing"
}When a free key has used its general allowance, the 429 says so and names what still works: You have used this month's free allowance of 2000 general requests. /api/v1/incidents/nearby keeps working up to 5000 requests in total.
- RateLimit-Reset
- Unix seconds at which the quota resets. Not a duration.
- Retry-After
- Seconds to wait, derived from the reset time. On a monthly quota this is legitimately large: it is telling you the truth, not malfunctioning.
- Per-IP throttling
- Separate from your plan quota and applied to unauthenticated routes such as password reset. Upgrading does not affect it, and its 429 says so.
Staying under the limit
Poll on a schedule that matches the data rather than the loop you happen to have. Feeds update between 30 seconds and 15 minutes depending on the agency, so polling incidents every second buys nothing except quota. One request a minute is 43,200 a month, which already needs a paid tier; one every five minutes is 8,640.
Filter server side. state, eventType and bounding-box parameters cost you one request instead of fetching everything and discarding most of it. See pagination for walking large result sets efficiently.