Search docs

Custom places

Add your own places (depots, customer addresses, private POIs) to search, autocomplete, reverse and place lookups of your account, beside the planet index.

By · Updated

Your own places are searched together with the planet index, by your account's keys only. They are stored beside the planet file, never inside it, and no other account can see them.

Write places

Writes take a secret key (gc_sk_…). Publishable keys and OAuth tokens get 403 secret_key_required. Writes count against the key's rate limit, not your geocoding allowance.

curl -X PUT https://api.geolith.app/v1/places/custom/depot-1 \
  -H "Authorization: Bearer $GEOLITH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Pune depot","names":{"mr":"पुणे डेपो"},"lat":18.5204,"lon":73.8567,"address":{"street":"FC Road","locality":"Pune","country":"IN"},"category":"depot"}'
Method and pathDoes
POST /v1/places/customWrite { "places": [...] }, insert or replace by externalId
POST /v1/places/custom/bulkWrite NDJSON, one place per line
PUT /v1/places/custom/{externalId}Write one place
GET /v1/places/custom?after=&limit=List by external id, up to 1,000 a page
GET /v1/places/custom/{externalId}Read one
DELETE /v1/places/custom/{externalId}Delete one
DELETE /v1/places/customDelete all

Writing an externalId you deleted earlier brings that place back with the new data.

The OpenAPI 3.1 description is at https://api.geolith.app/v1/places/openapi.json. You can also upload an NDJSON file and delete places in the dashboard at console.geolith.app.

A place

FieldRequiredNotes
externalIdyesYour id: 1–128 of A-Z a-z 0-9 . _ ~ -, unique in your account
nameyesUp to 200 characters
namesnoNames by language tag (hi, mr, ta, …); lang= picks one
lat, lonyes¹WGS 84 degrees; with an outline, the label point (optional, must lie inside)
geometryno¹GeoJSON Point, Polygon or MultiPolygon (RFC 7946, WGS 84)
addressnohousenumber, street, postalcode, locality, region, country (ISO alpha-2)
categorynoReturned as category: [..]
expiresAtnoISO 8601; after it the place is no longer returned, then deleted

¹ Give lat and lon, or a geometry. createdAt, createdBy, updatedAt, updatedBy, deletedAt and deletedBy are set by the server; a request that sends one gets 400.

Outlines: Polygon and MultiPolygon

A place can be an area: a yard, a campus, a delivery zone. Send a GeoJSON Polygon (an outer ring, then holes) or MultiPolygon (several polygons). Positions are [longitude, latitude].

curl -X PUT https://api.geolith.app/v1/places/custom/hadapsar-yard \
  -H "Authorization: Bearer $GEOLITH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Hadapsar yard",
    "category": "depot",
    "geometry": {
      "type": "Polygon",
      "coordinates": [
        [[73.920, 18.500], [73.930, 18.500], [73.930, 18.510], [73.920, 18.510], [73.920, 18.500]],
        [[73.924, 18.504], [73.924, 18.506], [73.926, 18.506], [73.926, 18.504], [73.924, 18.504]]
      ]
    }
  }'
curl -X PUT https://api.geolith.app/v1/places/custom/twin-depots \
  -H "Authorization: Bearer $GEOLITH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Twin depots",
    "geometry": {
      "type": "MultiPolygon",
      "coordinates": [
        [[[73.84, 18.52], [73.85, 18.52], [73.85, 18.53], [73.84, 18.53], [73.84, 18.52]]],
        [[[73.88, 18.55], [73.89, 18.55], [73.89, 18.56], [73.88, 18.56], [73.88, 18.55]]]
      ]
    }
  }'

Checked on write; a shape that fails gets 400 invalid_place with the reason:

  • Every ring is closed (first and last positions equal), with at least 3 distinct positions and some area.
  • Rings do not cross or touch each other or themselves; holes lie inside their outer ring; polygons of a MultiPolygon do not overlap.
  • Longitudes in -180, 180, latitudes in -90, 90. A shape across the antimeridian is cut there into a MultiPolygon (RFC 7946 §3.1.9); an edge across more than 180° of longitude is refused.
  • At most 10,000 positions per place and 100,000 per request.

Rings are rewound to the right-hand rule (outer rings counter-clockwise, holes clockwise). The place's point is its label point: the centroid of its largest polygon, or a point inside when the centroid falls outside (in a hole or a bend), unless you send lat/lon inside the shape.

In answers an outline place is returned the way planet places with outlines are:

  • /v1/search, /v1/autocomplete, /v1/reverse, /v1/nearby: a Point at the label point, with the outline's bbox ([west, south, east, north]; west > east across the antimeridian).
  • /v1/place?ids=custom:venue:<externalId>&geometry=true: the outline as the geometry (Polygon for one polygon, else MultiPolygon), the label point in properties.center, and the bbox.
  • /v1/reverse: a point inside the outline (not in a hole) returns the place whatever the radius; distances are to the label point.

addendum.custom.geometry_type says which kind a place is. GET /v1/places/custom/{externalId} returns the full geometry; the list returns geometryType, bbox and a small preview of each outer ring.

Limits

PlanCustom places
Free100
Starter1,000
Growth10,000
Scale100,000

One request writes at most 500 places in at most 5 MiB (413 payload_too_large). A write that would pass your plan's limit is refused whole, with nothing written (413 custom_places_limit).

In answers

  • /v1/search and /v1/autocomplete: a place of yours that holds every word of the query (the last word as a prefix in autocomplete) comes before the planet's places. boundary.country, layers (custom places are venue) and size apply.
  • /v1/reverse and /v1/nearby: your places within the radius, merged with the planet's by distance.
  • /v1/place: ask for custom:venue:<externalId> together with planet gids; answers keep the asked order.

Features have source: "custom", gid: "custom:venue:<externalId>", and addendum.custom with the names and expiry. A change made with the API shows in answers at once from the same location and everywhere within a minute. Structured search matches the address and locality words, and the MCP tools and A2A operations return your places the same way as the matching REST route.

Privacy

Places are visible only to your account's keys. They stop being returned when you delete them, when they expire, and when you close your account. Deleted places are kept, hidden, so we can restore them if you ask; to have them erased for good, write to contact@geolith.app.