Quotas & Rate Limits

Daily caps per tier, with X-RateLimit-* headers

3 min read
Print this section

FreeMaint API enforces a daily quota per company, reset at midnight UTC. The cap depends on your tier; counters and remaining are exposed as response headers.

Daily caps

  • Core, Starter โ€” 0 (an API key requires Business)
  • Business โ€” 5,000 calls/day (GraphQL and the energy ingest endpoint share the same counter)
  • Enterprise โ€” 100,000 calls/day
  • On-Premise โ€” unlimited (cap = null)

Response headers

  • X-RateLimit-Limit โ€” your tier's daily cap
  • X-RateLimit-Remaining โ€” calls left today (decrements on every quota-counted call)
  • X-RateLimit-Reset โ€” Unix timestamp of midnight UTC (next reset)

What doesn't count

Only /public-api/whoami is free โ€” it does not decrement your counter, so you can verify a key and its tier without burning quota. Everything on /api/v1/graphql is quota-counted, including the whoami query, and so is the energy ingest endpoint.

What counts as one call

The counter increments per OPERATION, not per HTTP request. Grouping 50 aliased mutations into a single request still consumes 50 units. Batching therefore saves round-trips, never quota. To keep a recurring sync affordable, pull only what changed with parts(updatedSince: "...") instead of re-reading the whole catalogue.

When you exceed the cap

Once you hit your daily cap, every further call is refused with the message 'Daily API cap reached'. On the REST surfaces (/public-api/ping, the energy ingest endpoint) that is an HTTP 403. On GraphQL the HTTP status is 200 and the refusal sits in errors[0].extensions.code = FORBIDDEN, with originalError.statusCode = 403. The counter resets at 00:00 UTC. There is no soft cap, no burst allowance and no per-minute window โ€” the window is the day.

Tip

Monitor X-RateLimit-Remaining in your integration's dashboard so you can warn yourself before hitting the cap.

Was this page helpful?