Skip to content

Reference

Errors

When a call fails, the answer says what went wrong and what to do next. Here is every error code, and how to handle each one.

What an error looks like

A call that fails answers with an HTTP status and an error object instead of data. This one comes from starting a collection after today's credits ran out:

HTTP/2 429
retry-after: 3600
x-request-id: 7c1e0b54-9a2f-4d3e-8f61-2b5a9c0d4e17
{
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "You reached your daily limit of 250 credits. Retry after midnight UTC. Buying credits does not raise this limit.",
    "messageKey": "serverErrors.quotaDay",
    "params": { "limit": 250 },
    "details": {
      "scope": "day",
      "limit": 250,
      "resetAt": "2026-09-25T00:00:00.000Z",
      "retryAfterSecs": 3600
    }
  }
}
  • code: what went wrong, as one of the codes below. Codes stay the same while messages can change, so have your program check code, not message.
  • message: the problem and what to do about it, in English. Log it, or show it to a person.
  • messageKey and params: a fixed key and the values that fill it, so an app can show the message in its own language. Most errors carry them.
  • details: more about this error, when there's more to say. For a bad request, it lists the fields that were wrong. For a limit, it says which one and when it resets.

The SDK throws the same fields as a GmapsError, with status, requestId and retryAfter added. Over MCP, a failed tool call comes back with isError: true and this object as its text.

Every error code

Each code always comes with the same HTTP status. The Whose side column says where the problem is: in your request, in your plan's limits, on our side or at Google Maps.

CodeStatusWhose sideWhat happenedWhat to do
VALIDATION_ERROR400YoursSomething in the request is missing or wrong. When it's a field, details lists each one with its path.Fix the request. Sent again as it is, it fails again.
UNAUTHORIZED401YoursThe call came without an API key, or not as Authorization: Bearer.Send your key as Authorization: Bearer gm_…. See Authentication.
INVALID_TOKEN401YoursThe key is wrong, revoked or expired, or it's a console sign-in token rather than an API key.Use an active key, or create a new one under API keys.
PLAN_GATE402Your planYour plan doesn't include this feature. details.gate names it, and details.upgradeTo names the plan that has it.Change plans under Plan, then retry. Waiting won't help.
AUP_REQUIRED403YoursEmail addresses need your acceptance of the current acceptable use policy, and your account doesn't have it yet. details.version is the version to accept.Read the policy, accept it in the console under Account, then retry.
FORBIDDEN403YoursYour account can't do this: it's suspended, or you asked to delete it.The message says which. To stop a deletion, sign in to the console and cancel it. Otherwise, write to support.
NOT_FOUND404YoursThere's no such route or id, or it belongs to another account.Check the method, the URL and the id.
PLACE_NOT_FOUND404YoursWe haven't saved this place, or we removed it after a removal request.Search its area to collect it, then look it up again. A removed place won't come back. See Places.
COLLECTION_NOT_FOUND404YoursYour account has no collection with this id.Check the id. GET /v1/collections lists yours.
EXPORT_NOT_FOUND404YoursThe export link is more than 24 hours old, its collection's places were deleted, or the link is wrong.Create a new export. If the collection is more than 30 days old, run it again first.
CONFLICT409YoursThe call clashes with how things stand now, such as cancelling a collection that already ended, or creating a key past your plan's limit.The message says what's in the way. Change that, then retry.
PAYLOAD_TOO_LARGE413YoursThe request body is larger than we accept. params.limit is the most, in bytes.Send a smaller body.
GEO_UNRESOLVED422YoursWe couldn't find the city you gave, or more than one city has that name. Only Brazilian cities work by name.Add the state, like Curitiba, PR, or pick one from details.candidates. Outside Brazil, send lat, lng and radiusM, or a bbox.
UPSTREAM_BLOCKED422Google MapsWe don't send this yet. It's kept for when Google Maps refuses our searches. Today, a collection whose searches fail ends with ENGINE_UNAVAILABLE instead.Nothing, for now. If you handle it anyway, try again later with a smaller area.
RATE_LIMIT_EXCEEDED429Your planYour account made more calls this minute than your plan allows.Wait the number of seconds in retry-after, then retry. details.limit is how many calls the limit allows, and details.window is how long it counts them: minute, or hour for the removal form.
QUOTA_EXCEEDED429Your planYou're out of credits for today or this month, or running as many collections as your plan allows. details.scope says which.It depends on details.scope. See the next section.
INTERNAL_ERROR500OursSomething broke on our side.Retry. If it keeps failing, write to support with the x-request-id.
ENGINE_UNAVAILABLE503OursWe couldn't run a collection's searches, so it found nothing and charged nothing. You see this on the collection's error, not as a failed call.Start the collection again in a few minutes. Searches still answer with the places we saved.
SERVICE_UNAVAILABLE503OursA service we depend on, such as our database, didn't answer.Retry after a few seconds. If it keeps failing, write to support.
BILLING_UNAVAILABLE503OursWe couldn't reach our payment provider, or payments aren't set up yet. Only the console's Plan page runs into this, never the API.Try again later. Nothing was charged.

Plan features and limits

Only PLAN_GATE answers 402. It means your plan doesn't include the feature, so waiting won't change the answer. details.upgradeTo names the cheapest plan that has it. Switch under Plan, then retry.

Using up a limit answers 429, and waiting clears it. RATE_LIMIT_EXCEEDED means too many calls this minute. QUOTA_EXCEEDED is about credits or collections, and details.scope says which:

  • month: this month's credits are spent, pack credits included. details.resetAt is the 1st of next month at midnight UTC. A credit pack lets you go on right away.
  • day: you reached today's limit. details.resetAt is the next midnight UTC. A pack doesn't raise it.
  • concurrency: you're running as many collections as your plan allows. Try again when one ends. This one has no resetAt.

Limits has every number for every plan.

When to try again

  • When the answer has a retry-after header, wait that many seconds, then send the same call again. RATE_LIMIT_EXCEEDED always has it, and so does QUOTA_EXCEEDED for day and month. The same number is in details.retryAfterSecs.
  • Any other 4xx: fix what the message names first. Sent again as it is, the call usually gets the same answer.
  • A 5xx is on our side. Try again after a few seconds, and wait a little longer after each failure. The SDK doesn't retry for you.

Asking us for help

Every answer, errors included, carries an x-request-id header. It points to that one call in our logs. When you write to support, send it along with what you sent and when.

You can also send your own x-request-id, such as the id your logs already use, so one id follows the call from your logs into ours. Use up to 64 letters, digits, dots, dashes and underscores, and nothing else. Otherwise we make a new one.

Never send us your API key. We don't need it to find the call.