Skip to content

Plans & Limits

Three plans. Every one of them includes every API: maps, geocoding, and routing are not sold separately.

The plans

Hobby (shown as dev on the pricing page): $0/month. 10,000 calls included per calendar month, counted only against non-dev-origin traffic (see below). No overage: once you are at the cap, further billable requests are blocked until the next month. No production origin can be listed on a key on this plan at all: dev origins only. It is for building and prototyping, not for serving a live domain.

Indie: $19/month. 250,000 calls included per month. Overage beyond that is $1.00 per 1,000 calls. One production origin per key, plus dev origins, which do not count against it.

Growth: $99/month. 2,000,000 calls included per month. Overage is $0.75 per 1,000 calls. Up to 100 production origins per key.

Included calls are counted per calendar month, UTC.

What counts as a call

Every request that passes authentication counts as one call, whatever the endpoint and whatever the status it returns: a tile, a style document, a geocoding query, a route, an isochrone. A 204 for an empty tile and a 400 for a bad parameter both count; a request rejected at the door (401, 429, 403) does not. A response served from the edge cache counts the same as one that reached a backend, because the cache is part of the service, not a way around it.

Two exceptions, both in your favour:

  • Glyph and sprite fetches are never metered. A single map load pulls many font ranges, and counting them would swamp your real usage and penalise label-dense maps. They are authenticated and rate-limited like everything else, just not billed.
  • Dev-origin traffic is counted but never billed. It shows in the dashboard under a dev: prefix so you can see it, and the monthly quota ignores it. The rule for what counts as a dev origin is next.

Because maps and geocoding draw from the same pool, a map that loads 40 tiles costs 40 calls, the same as 40 autocomplete keystrokes. Tiles are cached aggressively by MapLibre and by the browser, so a typical session pulls far fewer than a first paint suggests.

Dev origins are free, everywhere

A request whose Origin header, or the origin of its Referer when there is no Origin, is one of these does not count against any plan's included volume, on any plan:

  • localhost, 127.0.0.1, [::1], or any *.localhost hostname
  • any *.pages.dev or *.workers.dev hostname

That is a hostname match, not a substring match: notlocalhost.example.com does not qualify.

A request with no Origin or Referer header at all (the normal case for server-side calls) always counts as non-dev traffic. This is the one rule worth internalising early: calling the API from your backend, a script, or a mobile app is billable from the first request, even on the hobby plan, because there is no browser-supplied origin for the dev-origin check to exempt. Browser-side calls from localhost during development are the case that is actually free.

Spend cap

Indie and growth both default their spend cap to $0. That is not a display quirk. It means a paid plan hard-stops at its included call volume exactly like the free plan does, until you explicitly raise the cap in the dashboard. You will never be billed a surprise overage amount you did not opt into; you have to raise the cap first, and after that overage is billed at your plan's per-1,000-call rate.

What a block looks like

Plan enforcement runs as a job every five minutes, not on every request, so a key can run a few minutes past its limit before it is stopped, and a raised cap or a new month takes up to five minutes to lift the block. Once blocked, every request gets a 429 with a code that says why:

  • quota_exceeded is a hobby key at its 10,000 included calls. Clears on the first of the month.
  • spend_cap is a paid key whose overage has reached its spend cap. Clears when you raise the cap.
  • billing_required is a paid plan whose last payment failed. Clears when a retry succeeds after you update the payment method.

Origin enforcement is different: it is checked on every request and returns 403 with origin_not_allowed. It applies to any key, on any plan, that has a non-empty allowed-origins list, and it is strict once it applies: a request with no Origin or Referer, one whose header will not parse, and one from an origin that is not on the list all get the same refusal. A key with an empty list is unrestricted, which is what a server-side key should be. Dev origins are not implicit and have to be listed. See Errors for the bodies.

Rate limit

Separately from monthly volume, every key on every plan is capped at 1,000 requests per 60 seconds, per Cloudflare location. The blocked check (quota, spend cap, or a failed payment) runs first, so a key already blocked never reaches the rate limiter at all. This check applies after it, to every other request. It exists to bound abuse of a single key, not to enforce your plan's included volume. Going over it returns 429 with a Retry-After header; see Errors.

Checking where you stand

The dashboard shows your plan, spend cap, each key's allowed origins, and this month's call counts per endpoint, with dev-origin traffic broken out separately. It reads them from GET /account/me and GET /account/usage on the gateway, which authenticate with your browser session rather than an API key; they are not endpoints to embed in your application.