Open Places API
Guides Errors and Quota Headers

Places API

Errors and Quota Headers

Error response shape, every machine-readable error code, retry behavior, search warnings, and quota headers for the Open Places API.
On this page

Error format

Use stable codes for client behavior.

Search errors use stable machine-readable codes so callers can distinguish validation, auth, quota, coverage, and layer selection failures without parsing prose messages. Every error body carries code, message, request_id, and docs_url, a link to that code's entry on this page (https://openplacesapi.com/docs/errors#<code>). Validation errors add details, a list of field and message pairs for each rejected parameter.

JSON ErrorResponse
{
  "error": {
    "code": "validation_error",
    "message": "Invalid search request.",
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "details": [
      { "field": "radius_mi", "message": "radius_mi must be greater than 0 and at most 50." }
    ],
    "docs_url": "https://openplacesapi.com/docs/errors#validation_error"
  }
}

quota_exhausted also returns quota_limit and upgrade_url. Buy more searches from the dashboard billing page. There is no reset date or automatic charge.

JSON 402 quota_exhausted
{
  "error": {
    "code": "quota_exhausted",
    "message": "No searches left on this account. Buy more at https://app.openplacesapi.com/#billing.",
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "quota_limit": 2500,
    "upgrade_url": "https://app.openplacesapi.com/#billing",
    "docs_url": "https://openplacesapi.com/docs/errors#quota_exhausted"
  }
}

Statuses

HTTP status maps to the failure class.

Status Meaning
400 Invalid query parameter shape.
401 Missing bearer API key (unauthenticated) or invalid key (invalid_api_key).
402 Credit balance exhausted (quota_exhausted).
403 Requested layer selection is well-formed but unavailable to the authenticated account. layer_entry_cap_exceeded means the account is at its layer capacity: 250 entries before buying, 5,000 after any purchase. Archive entries, buy a pack, or email support@openplacesapi.com for more.
405 Only GET is supported.
422 Reserved for unsupported_query; not currently returned.
429 rate_limited: the burst limit (120 requests per minute per account and per key, for everyone) or the concurrency cap (8 searches in flight per account) was exceeded, or too many failed authentication attempts came from one IP.
500 Generic internal error.
503 Temporarily unavailable: coverage_not_ready, search_timeout, or quota_gate_unavailable. Retry after Retry-After seconds.

Error codes

Every public code and what to do about it.

Search errors link to their row through docs_url. Branch on code, not on message; messages can change wording.

Management and billing responses from app.openplacesapi.com use a different shape: {"error":{"code":"…","message":"…"}}, without the search API's request_id or docs_url fields. The two management and billing codes below are marked in their descriptions.

Code Status Meaning and client action
validation_error 400 A parameter is missing, malformed, out of range, or unknown. Read details for each rejected field, fix the request, and do not retry it unchanged.
unauthenticated 401 No bearer API key was sent. Send Authorization: Bearer opa_live_... from a server-side environment.
invalid_api_key 401 The key is malformed, revoked, or unknown. Check the stored secret or create a new key in the dashboard; retrying with the same key will not help.
method_not_allowed 405 Only GET is supported on /v1/places and /v1/categories.
unsupported_query 422 Reserved for recognized but unsupported search shapes. Not currently returned; unsupported inputs are rejected with validation_error.
layer_not_available 403 The layer selection is well-formed but not available to this account, or the preset does not exist. Check layers, layer_preset, or the key's default preset.
quota_exhausted 402 The prepaid search balance is zero or expired and the request was not billed. Stop retrying. Buy more searches at upgrade_url; there is no reset or automatic charge.
rate_limited 429 Too many requests per minute, more than 8 searches in flight for the account, or too many failed authentication attempts from one IP. Not billed. Wait Retry-After seconds and reduce request rate or parallelism.
coverage_not_ready 503 The data for this location is not ready to search yet. Retry after Retry-After seconds (30).
search_timeout 503 The search did not finish in time and was not billed. Retry after Retry-After seconds (5); a smaller radius or more specific query can help.
quota_gate_unavailable 503 The API key or quota could not be checked, or the search reservation expired. Retry after Retry-After seconds.
layer_entry_cap_exceeded 403 Management API: the account is at its layer-entry capacity (250 before a purchase, 5,000 afterward). Draft and published entries count; archive entries or email support for more capacity.
internal_error 500 Unexpected server error. Retry with backoff, and include request_id if you contact support.

Retries

Retry only what the API says is temporary.

When a response includes Retry-After, wait at least that many seconds before retrying. For rate_limited it is the time until the burst window resets, or 1 when the account hit the concurrency cap. For 503 codes it is a short backoff hint. quota_exhausted has no Retry-After or reset date. Stop and buy more at upgrade_url.

Each account can have at most 8 searches in flight at once. Requests over the cap are rejected immediately with rate_limited and are not billed. Bound client-side parallelism to stay under the cap.

Search warnings

Empty results explain themselves.

Successful searches can include meta.warnings, a list of code and message objects. Warnings do not change the HTTP status. unknown_category and no_results_within_radius are only added to an empty first page (offset=0 with no results).

Warning Meaning and client action
category_alias A reviewed legacy category was resolved to resolved_category, also returned in meta.category. This warning can appear on any successful page. Legacy parent aliases can narrow the old filter; check the resolved slug against the scope you need.
unknown_category The category value is not a known Overture category. suggestions lists the closest known slugs when any are found. Retry with one of them, or look slugs up with GET /v1/categories.
no_results_within_radius Nothing matched within radius_mi. When a match was found within 100 miles, nearest_match identifies the closest place found (public id, name, distance_mi, and locality and country when available). It stays outside results. nearest_match_distance_mi gives the same approximate distance and the message names the radius_mi to retry with, or says the match is beyond the 50 mile maximum so the search should start from a closer point. Without that field, nothing was found within 100 miles.
address_matching_skipped A short mode=all query searched names only. Use a longer query to include addresses.
query_relaxed q had no exact matches, so the search was retried once with a relaxed form of q (legal suffixes such as LLC, parenthesized asides, and connector words removed). The message names the text used. Check that the results are the place you meant before relying on them.
category_inferred No place names matched q, even relaxed, so it was read as the closest category by meaning (for example travel agency as travel_agent). The results are nearby places in that category, named in the message and in meta.interpreted_as; none of them is a place called q. Use mode=name to turn this off.
pagination_limit_reached More places match a category browse than its 1,000-place window can page through, so next_offset is null even though the results continue. Narrow radius_mi, raise min_confidence, or add q to reach the rest.
layer_entries_truncated The per-search layer read limit was reached, so some published layer entries were not applied.
JSON meta.warnings
{
  "warnings": [
    {
      "code": "unknown_category",
      "message": "\"coffeeshop\" is not a known category. Closest known categories: coffee_shop. List categories with GET /v1/categories?q=<text>.",
      "suggestions": ["coffee_shop"]
    }
  ]
}

Headers

Quota and retry metadata travel in headers.

X-Quota-Limit and X-Quota-Remaining are sent on successful searches and quota_exhausted responses. Other failures, including invalid keys and validation errors, do not carry quota headers.

Header Use
X-Request-ID Server-generated request identifier for support and debugging.
X-Quota-Limit Current credit balance allocation.
X-Quota-Remaining Unused, unexpired searches in the current balance.
Retry-After Seconds to wait before retrying after rate_limited or a 503. A credit balance never resets.