๐Ÿ”ฅ Try Handled Locator free for 7 days.Start free trial

Developers

Location API

Create, read, update and delete locations from your own systems, and query them for a custom front end.

Create a key

An account owner creates API keys in Settings โ†’ API & developer tools. Give the key a name describing what will use it, and decide whether it may write.

The key is shown once, at creation. Handled stores only a hash of it, so it cannot be displayed again โ€” if it is lost, revoke it and create another.

The API is available on the Pro and Business plans.

Authentication

Send the key as a bearer token. Requests without one, or with a revoked one, return 401.

curl
curl -H "Authorization: Bearer $HANDLED_KEY" \
"https://app.handledlocal.com/api/v1/locations?limit=5"

Rate limits are per key: 120 reads and 30 writes per minute. Exceeding either returns 429.

Endpoints

  • GET /api/v1/locations lists locations, newest first. Accepts limit (max 200), offset, visibility and search. Returns a pagination object with total and hasMore.
  • GET /api/v1/locations/:id returns one location.
  • POST /api/v1/locations creates one. name is required.
  • PATCH /api/v1/locations/:id updates one. Only the fields you send change.
  • DELETE /api/v1/locations/:id removes one from the locator. This is a soft delete, matching the dashboard: analytics history for that location survives.
Create a location
curl -X POST "https://app.handledlocal.com/api/v1/locations" \
-H "Authorization: Bearer $HANDLED_KEY" \
-H "Content-Type: application/json" \
-d '{
  "name": "Katy Freeway Store",
  "address": "1000 Katy Fwy, Houston, TX 77024",
  "phone": "+1 713 555 0100",
  "hours": { "1": { "open": "09:00", "close": "17:00" }, "7": null },
  "customFields": { "Manager": "Dana" }
}'

Send an address without lat and lng and Handled geocodes it for you, filling in city, state, postcode and country. If the lookup fails the location is still created, marked so it appears in the dashboard's list of locations needing attention โ€” the same place a failed CSV row lands.

Absent is not null

On a PATCH, leaving a field out means "leave it alone" and sending null means "clear it". They are different instructions, which is what makes it safe for two systems to update different fields of the same location.

Change only the phone number
curl -X PATCH "https://app.handledlocal.com/api/v1/locations/$ID" \
-H "Authorization: Bearer $HANDLED_KEY" \
-H "Content-Type: application/json" \
-d '{ "phone": "+1 713 555 0199" }'

Query API

GET /api/v1/query answers "what is near this point", for building your own store-finder page or a mobile app. Results come back nearest-first with a distance, ranked by the same function the widget itself uses, so your page and your locator agree.

Nearest five within 25 miles
curl -H "Authorization: Bearer $HANDLED_KEY" \
"https://app.handledlocal.com/api/v1/query?near=29.76,-95.36&radius=25&units=mi&limit=5"

Accepts near (as lat,lng), radius, units (km or mi), tag, q and limit. Without near it returns locations in the locator's own order, highest priority first.

Hidden locations stay hidden unless you pass includeHidden=true, so a location you paused in the dashboard cannot reappear through a page built on this endpoint. Online stockists have no coordinates and are therefore left out of distance queries.

Errors

Failures return a JSON body of the form { "error": { "code": "...", "message": "..." } }.

  • 401 missing_key / invalid_key โ€” no bearer token, or one that is not valid or has been revoked.
  • 403 plan_required โ€” the account is not on a plan that includes the API.
  • 403 read_only_key โ€” a write was attempted with a read-only key.
  • 403 location_limit_reached โ€” creating this location would exceed the plan's allowance. Includes limit and current.
  • 422 validation_failed โ€” includes a fields array naming each field and what was wrong with it.
  • 429 rate_limited โ€” too many requests for this key this minute.

What this API does not do

There are no webhooks: nothing calls your systems when a location changes in Handled, so keep the schedule on your side. Categories are created in the dashboard rather than through the API โ€” tag filters against ones that already exist. Widget settings, branding and labels are not exposed here.