Skip to main content

Errors

All errors are returned as application/json regardless of the requested output format.

HTTP status codes

StatusMeaningWhen it happens
200 OKSuccessMap rendered and returned.
304 Not ModifiedCached — no bodySent when If-None-Match matches the current ETag.
400 Bad RequestValidation or parser failureA parameter value is invalid — wrong type, out of range, missing scope, or a data/markers/routes/patterns/annotations string could not be parsed.
404 Not FoundUnknown scopeThe scope value is not in the loaded topology.
413 Content Too LargeBody too largePOST body exceeds 4 MB.

Error shape

Every error response has this JSON structure:

{
"error": "error_code",
"message": "Human-readable description of the problem.",
"status": 400
}
  • error — a machine-readable code identifying the specific error.
  • message — a human-readable explanation, often including the invalid value and what was expected.
  • status — mirrors the HTTP status code.

Example 400 — invalid theme:

{
"error": "invalid_theme",
"message": "theme \"ocean\" not found. Available: light, light-blue, light-mono, dark, dark-blue, dark-mono",
"status": 400
}

Example 400 — missing scope:

{
"error": "missing_scope",
"message": "scope is required",
"status": 400
}

Example 404 — unknown scope:

{
"error": "invalid_scope",
"message": "Scope \"eu\" not found",
"status": 404
}

Example 400 — malformed data parameter:

{
"error": "invalid_data",
"message": "bad pair \"US-abc\" (expected id:value[:color])",
"status": 400
}

Common mistakes

Invalid scope

scope must exactly match a loaded topology ID. IDs are case-sensitive. Use the Scopes list to find the correct value.

# Wrong — lowercase
?scope=ro

# Correct
?scope=RO

Malformed data=

Each pair must be id:value or id:value:#rrggbb. The # must be URL-encoded as %23.

# Wrong — missing value
?data=US,CN,DE

# Wrong — unencoded #
?data=US:100:#ff0000

# Correct — value only
?data=US:100,CN:80,DE:60

# Correct — with per-region color override
?data=US:100:%23ff0000,CN:80,DE:60

Mixing data= and regions=

data= and regions= serve different modes. data= encodes numeric values for choropleth fills; regions= is highlight-only with no values. They are processed separately and merged, but passing both for the same region ID produces undefined colour precedence. Use one or the other per region.

Oversized POST body

The POST endpoint accepts up to 4 MB. If your payload exceeds this limit, the server returns 413. Consider:

  • Reducing decimal precision in value fields.
  • Omitting regions with null values if you only want to highlight a subset.
  • Splitting annotation strings that are close to the 200-character limit.

Too many regions

The maximum is 5000 regions per request. Requests exceeding this return:

{
"error": "too_many_regions",
"message": "region count exceeds limit (5000)",
"status": 400
}