ZeeMaps API Docs Guides Quickstart Get a key ZeeMaps.com ↗

ZeeMaps REST API (1.0.0)

Download OpenAPI specification:

The ZeeMaps REST API allows enterprise customers to programmatically create and manage maps and markers, and perform geographic searches.

Internal naming note for implementers: a user-facing "map" is the ZeeMaps Group domain object (com.zeesource.maps.Group), and a "marker" is an com.zeesource.maps.entries.Entry (table NewEntries). The public API uses the terms "map" and "marker" throughout; do not expose "group"/"entry".

Authentication

All requests must include an API key in the Authorization header:

Authorization: Bearer <api_key>

Keys are minted by ZeeMaps on request (any account may request one), stored only as a SHA-256 hash, and returned in full once at mint time. Multiple keys per account are supported (e.g. "Production", "Staging"), each with a read_only or read_write scope. A read_only key is rejected with 403 on any write (POST/PATCH/DELETE) endpoint.

API access requires the enterprise plan. A valid key whose account is not on the enterprise plan is rejected with 402 PLAN_REQUIRED on every endpoint.

Identifiers

map_id and marker_id are positive integers — the underlying ZeeMaps record IDs — and are returned as JSON numbers, not strings. Because IDs are sequential and enumerable, every endpoint strictly enforces ownership (see below); a valid key may only reach maps the account owns. Maps merely shared to the account are not accessible through the API.

Rate Limiting

Rate limits are enforced per API key. Limit details are returned in response headers on every response:

  • X-RateLimit-Limit: requests allowed per minute
  • X-RateLimit-Remaining: requests remaining in current window
  • X-RateLimit-Reset: Unix timestamp when the window resets

When the limit is exceeded the API returns 429 with a Retry-After header.

Pagination

List endpoints return cursor-based pages:

  • Pass page_token from next_page_token in the previous response
  • Default page size is 100; maximum is 1000 via page_size

Errors

All errors follow a consistent structure:

{ "error": { "code": "NOT_FOUND", "message": "Map not found" } }

Codes: UNAUTHORIZED (401), PLAN_REQUIRED (402), FORBIDDEN (403), NOT_FOUND (404), BAD_REQUEST (400), RATE_LIMITED (429), INTERNAL_ERROR (500). PLAN_REQUIRED means the account must upgrade to the enterprise plan to use the API. On 401 and 402 the error may include a help_url deep-linking the user to the request-a-key or upgrade page.

Account

Who am I

Returns the account, scope, plan, and rate limit behind the current API key. Lets a client self-configure and detect plan/scope before making other calls.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "account_email": "ops@acme.example",
  • "scope": "read_write",
  • "plan": "enterprise",
  • "rate_limit": 30
}

Maps

List maps

Lists maps owned by the authenticated account. Defaults to active maps; use status=archived for the archived view. Maps shared to the account are not listed (owned-only API).

Authorizations:
ApiKeyAuth
query Parameters
page_size
integer <= 1000
Default: 100

Maximum number of items to return per page. Defaults to 100; values above the maximum of 1000 are capped.

page_token
string

Cursor token from a previous list response

q
string

Filter maps by name (partial match)

status
string
Default: "active"
Enum: "active" "archived"

Lifecycle filter (archived = Groups.status 2).

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "page_info": {
    }
}

Create a map

Creates a new map owned by the authenticated account. New maps are private by default. Returns the created map.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
name
required
string

Title for the new map.

description
string

Optional "About" text for the map (stored as MapProps.about).

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "id": 4321179,
  • "name": "US Sales Territories Q3 2026",
  • "description": "string",
  • "owner_email": "string",
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "private": true,
  • "extended_colors": true,
  • "marker_count": 0,
  • "region_count": 0
}

Get a map

Fetches a single owned map by id, including marker and region counts. Returns 404 if the map doesn't exist, is deleted, or isn't owned by the account.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Responses

Response samples

Content type
application/json
{
  • "id": 4321179,
  • "name": "US Sales Territories Q3 2026",
  • "description": "string",
  • "owner_email": "string",
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "private": true,
  • "extended_colors": true,
  • "marker_count": 0,
  • "region_count": 0
}

Update a map

Applies a partial update (name, description, and/or private) to an owned map. Only the supplied fields are changed.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Request Body schema: application/json
required
name
string

New map title.

description
string

New "About" text for the map (MapProps.about).

private
boolean

Make the map private (true) or public (false).

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "private": true
}

Response samples

Content type
application/json
{
  • "id": 4321179,
  • "name": "US Sales Territories Q3 2026",
  • "description": "string",
  • "owner_email": "string",
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "private": true,
  • "extended_colors": true,
  • "marker_count": 0,
  • "region_count": 0
}

Delete a map

Soft-deletes the map (sets Groups.status = 1), matching the web app's own delete behavior. The map stops appearing in list/get responses but the row is retained and is recoverable. Returns 204.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Clone a map

Clones an owned map into a new copy owned by the caller, optionally including its markers and/or regions. Returns the new map.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Request Body schema: application/json
required
name
required
string

Name for the cloned map

include_markers
boolean
Default: true

Copy the source map's markers into the clone (default true).

include_regions
boolean
Default: true

Copy the source map's regions into the clone (default true).

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "include_markers": true,
  • "include_regions": true
}

Response samples

Content type
application/json
{
  • "id": 4321179,
  • "name": "US Sales Territories Q3 2026",
  • "description": "string",
  • "owner_email": "string",
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "private": true,
  • "extended_colors": true,
  • "marker_count": 0,
  • "region_count": 0
}

Archive a map

Moves the map to the archived state (Groups.status = 2).

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Responses

Response samples

Content type
application/json
{
  • "id": 4321179,
  • "name": "US Sales Territories Q3 2026",
  • "description": "string",
  • "owner_email": "string",
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "private": true,
  • "extended_colors": true,
  • "marker_count": 0,
  • "region_count": 0
}

Restore a map

Restores an archived or soft-deleted map to the active state (Groups.status = 0). Paid feature — non-paid accounts get 402/403.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Responses

Response samples

Content type
application/json
{
  • "id": 4321179,
  • "name": "US Sales Territories Q3 2026",
  • "description": "string",
  • "owner_email": "string",
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "private": true,
  • "extended_colors": true,
  • "marker_count": 0,
  • "region_count": 0
}

Transfer map ownership

Reassigns ownership of the map to another account. Owner or superuser only.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Request Body schema: application/json
required
new_owner_email
required
string

Email of the new owner. A pending account is created if it doesn't exist.

Responses

Request samples

Content type
application/json
{
  • "new_owner_email": "string"
}

Response samples

Content type
application/json
{
  • "error": {
    }
}

Enable the extended color palette

Switches the map to the extended color palette (MapProps.extendedColors, via the SetExtendedColors DB function). One-way — there is no way to revert to the standard palette. Idempotent if already enabled. Returns the updated map.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Responses

Response samples

Content type
application/json
{
  • "id": 4321179,
  • "name": "US Sales Territories Q3 2026",
  • "description": "string",
  • "owner_email": "string",
  • "status": "active",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "private": true,
  • "extended_colors": true,
  • "marker_count": 0,
  • "region_count": 0
}

List shares

Lists the users this map is shared with.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Responses

Response samples

Content type
application/json
{
  • "shares": [
    ]
}

Share a map

Shares the map with a user at the given access level. If the email has no ZeeMaps account, a pending account is created and a set-password link sent.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Request Body schema: application/json
required
email
required
string

Email of the user to share the map with. If no ZeeMaps account exists for it, a pending account is created and a set-password link is emailed.

access_level
required
string (ShareAccessLevel)
Enum: "viewer" "member" "admin"

Access granted to a shared user (maps to the ZeeMaps AccessLevel enum: Viewer/Member/Admin). none is represented by the absence of a share.

Responses

Request samples

Content type
application/json
{
  • "email": "string",
  • "access_level": "viewer"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "email": "string",
  • "access_level": "viewer",
  • "pending": true
}

Update a share

Changes the access level of an existing share.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

share_id
required
integer <int64>

Numeric identifier of a share (Shares row)

Request Body schema: application/json
required
access_level
required
string (ShareAccessLevel)
Enum: "viewer" "member" "admin"

Access granted to a shared user (maps to the ZeeMaps AccessLevel enum: Viewer/Member/Admin). none is represented by the absence of a share.

Responses

Request samples

Content type
application/json
{
  • "access_level": "viewer"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "email": "string",
  • "access_level": "viewer",
  • "pending": true
}

Revoke a share

Revokes a collaborator's access by removing the share. Returns 204.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

share_id
required
integer <int64>

Numeric identifier of a share (Shares row)

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Markers

List custom fields

Lists the map's custom field definitions (Attributes). Useful for clients (e.g. the MCP server) to discover which custom_fields keys a map uses before reading/writing markers. Read-only — fields are created implicitly when markers are written with new custom_fields keys.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Responses

Response samples

Content type
application/json
{
  • "fields": [
    ]
}

List available palette colors

Lists the color names available for this map's active palette (standard or extended, per extended_colors). Use the returned name values as a marker color. Read-only.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Responses

Response samples

Content type
application/json
{
  • "extended": false,
  • "colors": [
    ]
}

List categories

Lists the map's categories and their legend colors (from MapProps.legends). Categories are created implicitly when markers are written with a new category value (color auto-assigned); to rename, recolor, or reorder them, use PUT /maps/{map_id}/categories.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Responses

Response samples

Content type
application/json
{
  • "categories": [
    ]
}

Replace the legend (edit / reorder categories)

Full replace of the map's legend (same model as the web app's legend editor): the submitted category list becomes the legend, in the given order. Use it to rename a category (markers keep their color), reassign a color, or re-order legend entries. Markers are never modified. When the map has exactly one layer the default layer's legend is kept in sync.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Request Body schema: application/json
required
required
Array of objects

The new legend, in display order.

Responses

Request samples

Content type
application/json
{
  • "categories": [
    ]
}

Response samples

Content type
application/json
{
  • "categories": [
    ]
}

Clear all legends

Clears the map's legend/category mappings (maps to /legends/clear?all=true). Does NOT delete markers — they keep their assigned color; only the legend labels/mappings are reset. Returns 204.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

List markers

Lists markers on the map's default layer, cursor-paginated. To filter by category, geographic bounds, or proximity, use GET .../markers/search.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

query Parameters
page_size
integer <= 1000
Default: 100

Maximum number of items to return per page. Defaults to 100; values above the maximum of 1000 are capped.

page_token
string

Cursor token from a previous list response

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "page_info": {
    }
}

Add a marker

Adds a single marker to the map's default layer. Supply lat+lng, or an address to be geocoded server-side (there is no standalone geocode endpoint). Returns the created marker.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Request Body schema: application/json
required
name
required
string

Marker label/name.

type
string
Enum: "pin" "us_zip" "us_county" "country" "au_state" "us_state" "circle" "ca_fsa" "uk_postcode" "pinned_circle" "au_postcode" "de_postcode"

Defaults to pin.

object (Address)

Structured address (NewEntries street/city/state/country/zipcode + AddressLine2). There is no single free-text address column; supply the parts. For postal region types (us_zip, ca_fsa, uk_postcode, au_postcode, de_postcode) the zip field drives region resolution; for spatial region types (us_county, us_state, au_state, country) resolution uses lat/lng.

lat
number <double>

Provide lat+lng, OR an address with no coordinates to have the server geocode it. There is no standalone geocode endpoint.

lng
number <double>

Longitude. Provide with lat, or supply an address to geocode.

radius
number <double>

Required for circle / pinned_circle types.

radius_unit
string
Default: "miles"
Enum: "miles" "km"

Unit for radius (miles or km). Defaults to miles.

category
string

Legend category for the marker; drives its color (auto-assigned from the category).

color
string

Palette color name; normally omitted (derived from category).

object

Map-defined custom field values, as a key→string map. New keys create new field definitions on the map.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "type": "pin",
  • "address": {
    },
  • "lat": 0.1,
  • "lng": 0.1,
  • "radius": 0.1,
  • "radius_unit": "miles",
  • "category": "string",
  • "color": "string",
  • "custom_fields": {
    }
}

Response samples

Content type
application/json
{
  • "id": 88341027,
  • "map_id": 0,
  • "name": "Acme Corp HQ",
  • "type": "pin",
  • "address": {
    },
  • "lat": 37.7879,
  • "lng": -122.3983,
  • "radius": 0,
  • "radius_unit": "miles",
  • "category": "string",
  • "color": "string",
  • "custom_fields": {
    },
  • "region_source": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Bulk add markers

Add many markers in a single request. Bulk add is always asynchronous: the upload is handed to the shared ZeeMaps import service (Bin/import) — which owns encoding detection, hybrid geocoding + cache, and dedup/overwrite — and the endpoint returns 202 Accepted + a BulkJob. Poll GET /v1/jobs/{job_id} for progress. All imports are scoped to the map's default layer.

Three request content types are accepted:

  1. text/csv — a raw CSV. Columns are recognized per column, in order: exact ZeeMaps field names (name, lat, lng, street, street2, city, state, zip, country, county, category, photo_url, photo_width, photo_height, youtube_id, video_width, video_height, …) and the display names ZeeMaps itself exports ("Photo URL", "Photo Width", "Zipcode", "Color", …); then a header row previously confirmed in the web upload UI (header memory); then AI classification with a regex fallback — the same pipeline as the web upload. Anything still unrecognized becomes a custom field named after its header. Set auto_map=false to skip the memory/AI steps (strict exact-name matching only). The AI step runs synchronously before the 202 and typically adds ~0.5–2 s; it is skipped when every column already resolves exactly, and an AI failure is fail-open (the import still runs).
  2. application/json — a JSON array of marker objects (the same shape as MarkerCreateRequest: name, lat/lng or address {}, category, custom_fields). Per-marker type/color/radius are not supported — the importer applies one marker_type and default per batch. auto_map defaults to false for this shape: custom_fields keys stay custom fields verbatim and no AI call is made. Pass auto_map=true to have unrecognized keys classified into special columns like the CSV shapes.
  3. multipart/form-data — a file part (the spreadsheet; CSV in v1) plus a meta JSON part (BulkImportMeta) carrying a column_mapping ({apiField: columnRef}, the column by header name or 0-based index), an optional ignore list of column names, and options (marker_type, on_duplicate, default_country, auto_map). An explicit mapping always wins; unmapped columns go through the same recognition steps as text/csv. Use this when the spreadsheet's columns don't match ZeeMaps field names.

For text/csv and application/json, batch options are passed as the query parameters on_duplicate, default_country, marker_type, and auto_map (the multipart form carries them inside meta instead).

Row limit: bounded by the map's subscription/plan limit (uploadexceedslimit), not a fixed constant. Over-limit requests are rejected with 400.

# text/csv shape (ZeeMaps-named headers)
name,street,city,state,zip,category
Acme Corp,350 Mission St,San Francisco,CA,94105,Gold
Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

query Parameters
on_duplicate
string
Default: "skip"
Enum: "skip" "overwrite" "error"

(text/csv and application/json only) How to handle a row that matches an existing marker. Only overwrite is acted on by the importer (it overwrites the match); otherwise rows are inserted. For multipart uploads set this inside the meta part.

default_country
string

(text/csv and application/json only) Country code applied to rows that have no country of their own (importer defCountry); defaults to US. For multipart uploads set this inside the meta part.

marker_type
string (MarkerType)
Enum: "pin" "us_zip" "us_county" "country" "au_state" "us_state" "circle" "ca_fsa" "uk_postcode" "pinned_circle" "au_postcode" "de_postcode"

(text/csv and application/json only) Marker type applied to every imported row (the importer applies one type per import); defaults to pin. For multipart uploads set this inside the meta part.

auto_map
boolean

(text/csv and application/json only) Automatically recognize columns the way the web upload does (header memory, then AI classification with a regex fallback) after exact field names/aliases are applied. Set false for strict, deterministic exact-name matching with no AI call (minimal pre-processing latency). Defaults to true for text/csv and false for application/json (whose custom_fields are explicitly custom). For multipart uploads set this inside the meta part (defaults to true there).

object (DemographicsConfig)

(text/csv and application/json only) Demographic-enrichment config as a URL-encoded JSON object. For multipart uploads set this inside the meta part instead.

object (ChoroplethConfig)

(text/csv and application/json only) Choropleth config as a URL-encoded JSON object (use value_field = a column name or demo:<key>). For multipart uploads set this inside the meta part instead.

Request Body schema:
required
string <binary>

A CSV whose header row uses ZeeMaps field names. Unmapped columns become custom fields.

Responses

Request samples

Content type
No sample

Response samples

Content type
application/json
{
  • "job_id": "918273",
  • "kind": "bulk_import",
  • "status": "completed",
  • "status_url": "/v1/jobs/918273",
  • "added": 1450,
  • "skipped": null,
  • "errors": [
    ],
  • "created_at": "2026-06-30T17:10:00Z"
}

Bulk delete markers

Delete markers by all (clear the map), marker_ids, or a color-based selection (categories and/or colors). Requires confirm: true.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Request Body schema: application/json
required
all
boolean
Default: false

Delete every marker on the map (clears the map). Maps to the efficient cascading delete_all operation. Mutually exclusive with the other selectors. Legends are NOT cleared (use DELETE /maps/{id}/categories).

marker_ids
Array of integers <int64> [ items <int64 > ]

Explicit list of marker IDs to delete.

categories
Array of strings

Delete all markers in these categories. Each category label is resolved to its color id via the map legend (MapProps.legends), then deleted via deleteOfColor.

colors
Array of strings

Delete all markers of these palette color names (e.g. "blue", "Hot Pink"). Each name is resolved to a color id against the map's active palette — standard (Colors/StdColors) or extended (ExtColors) per the map's extended-colors setting. May be combined with categories.

confirm
boolean
Default: false

Must be true to execute bulk delete.

Responses

Request samples

Content type
application/json
{
  • "all": false,
  • "marker_ids": [
    ],
  • "categories": [
    ],
  • "colors": [
    ],
  • "confirm": false
}

Response samples

Content type
application/json
{
  • "deleted": 0
}

Get a marker

Fetches a single marker from the map's default layer by id. Returns 404 if no such marker exists on the map.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

marker_id
required
integer <int64>
Example: 88341027

Numeric identifier of the marker

Responses

Response samples

Content type
application/json
{
  • "id": 88341027,
  • "map_id": 0,
  • "name": "Acme Corp HQ",
  • "type": "pin",
  • "address": {
    },
  • "lat": 37.7879,
  • "lng": -122.3983,
  • "radius": 0,
  • "radius_unit": "miles",
  • "category": "string",
  • "color": "string",
  • "custom_fields": {
    },
  • "region_source": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Update a marker

Applies a partial update to a marker on the map's default layer; only supplied fields change. Changing the address or lat/lng re-geocodes the marker.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

marker_id
required
integer <int64>
Example: 88341027

Numeric identifier of the marker

Request Body schema: application/json
required
name
string

New marker label/name.

type
string (MarkerType)
Enum: "pin" "us_zip" "us_county" "country" "au_state" "us_state" "circle" "ca_fsa" "uk_postcode" "pinned_circle" "au_postcode" "de_postcode"

ZeeMaps marker type (internally "marktype"). Type is per-marker — a single map may contain a mix. Region types render as a filled area rather than a pin; the polygon is resolved server-side from the marker's location/postcode by SetMarkType and recorded in EntryState (see region_source). On no match the marker falls back to a pin. Internal codes: pin=0, us_zip=1, us_county=2, country=3, au_state=4, us_state=5, circle=6, ca_fsa=7, uk_postcode=8, pinned_circle=9, au_postcode=10, de_postcode=11.

object (Address)

Structured address (NewEntries street/city/state/country/zipcode + AddressLine2). There is no single free-text address column; supply the parts. For postal region types (us_zip, ca_fsa, uk_postcode, au_postcode, de_postcode) the zip field drives region resolution; for spatial region types (us_county, us_state, au_state, country) resolution uses lat/lng.

lat
number <double>

New latitude (provide with lng).

lng
number <double>

New longitude (provide with lat).

radius
number <double>

New radius for circle/pinned_circle markers, in radius_unit.

radius_unit
string
Enum: "miles" "km"

Unit for radius (miles or km).

category
string

New legend category (reassigns the marker's color).

color
string

Palette color name to set explicitly (overrides the category-derived color).

object

Custom field values to set, as a key→string map.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "type": "pin",
  • "address": {
    },
  • "lat": 0.1,
  • "lng": 0.1,
  • "radius": 0.1,
  • "radius_unit": "miles",
  • "category": "string",
  • "color": "string",
  • "custom_fields": {
    }
}

Response samples

Content type
application/json
{
  • "id": 88341027,
  • "map_id": 0,
  • "name": "Acme Corp HQ",
  • "type": "pin",
  • "address": {
    },
  • "lat": 37.7879,
  • "lng": -122.3983,
  • "radius": 0,
  • "radius_unit": "miles",
  • "category": "string",
  • "color": "string",
  • "custom_fields": {
    },
  • "region_source": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Delete a marker

Deletes a marker from the map's default layer. Returns 204 on success, or 404 if no such marker exists on the map.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

marker_id
required
integer <int64>
Example: 88341027

Numeric identifier of the marker

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

List available demographic fields

The global catalog of demographic fields selectable in a bulk import's demographics config — reference each by id or key. Auth-gated but not map-scoped.

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "demographic_fields": [
    ]
}

Search

Search markers

Full-text and geo search across markers on a map.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

query Parameters
q
string

Text search across name, description, address, and custom fields. MVP uses ILIKE substring matching (markers have no tsvector index today).

category
string
bounds
string

Bounding box: sw_lat,sw_lng,ne_lat,ne_lng (PostGIS ST_Within on NewEntries.location)

near
string

Center point + radius: lat,lng,radius_km — e.g. 37.77,-122.41,50 (PostGIS ST_DWithin)

page_size
integer <= 1000
Default: 100

Maximum number of items to return per page. Defaults to 100; values above the maximum of 1000 are capped.

page_token
string

Cursor token from a previous list response

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "page_info": {
    }
}

Images

Render a standard map image

Render a standard image of the map (PNG or PDF) — the API equivalent of the web app's Print / Share → PDF/PNG. v1 exposes a fixed set of layouts via preset (pin coverage, US, world, regions) rather than arbitrary bounds or dimensions, so output stays small. Rendering is heavyweight (Mapnik), so it always runs asynchronously: returns 202 + an ImageJob; poll GET /v1/jobs/{job_id} and download image_url once complete. Images are un-watermarked and covered by the enterprise plan at no extra charge. Owned-only.

Authorizations:
ApiKeyAuth
path Parameters
map_id
required
integer <int64>
Example: 4321179

Numeric identifier of the map (ZeeMaps Group ID)

Request Body schema: application/json
required
preset
required
string
Enum: "pin_coverage" "us" "world" "regions"

Which standard layout to render — pin_coverage: fit to the bounding box of all markers (pins); us: continental US map; world: whole-world map; regions: fit to the bounding box of the map's region markers.

format
string
Default: "png"
Enum: "png" "pdf"

Output file format.

map_type
string
Default: "map"
Enum: "map" "satellite"

Base layer — street map or satellite imagery.

paper_size
string
Default: "letter"
Enum: "letter" "a4"

Page size for the render. Bounded to standard sizes only — no Poster or custom dimensions; large renders are intentionally not offered in v1.

orientation
string
Default: "landscape"
Enum: "landscape" "portrait"

Page orientation. Landscape by default, matching the web map export.

legend
boolean
Default: false

Draw the category legend on the image (off by default, matching the web export).

title
boolean
Default: true

Draw the map title (the map name) on the image.

labels
boolean
Default: false

Draw marker labels on the image.

Responses

Request samples

Content type
application/json
{
  • "preset": "us",
  • "format": "png",
  • "map_type": "map",
  • "paper_size": "letter",
  • "legend": true
}

Response samples

Content type
application/json
{}

Jobs

Get job status

Poll the status of an async operation — a bulk marker import (BulkJob) or a standard image render (ImageJob); the kind field discriminates them. Owned-only — returns the job only if its map is owned by the calling account; otherwise 404.

Authorizations:
ApiKeyAuth
path Parameters
job_id
required
string^[A-Za-z0-9_]+$

Identifier of an async job — a bulk-import csvid (e.g. 2652) or an image render id (e.g. img_979_4a3c192010e1496d).

Responses

Response samples

Content type
application/json
Example
{
  • "job_id": "918273",
  • "kind": "bulk_import",
  • "status": "completed",
  • "status_url": "/v1/jobs/918273",
  • "added": 1450,
  • "skipped": null,
  • "errors": [
    ],
  • "created_at": "2026-06-30T17:10:00Z"
}