Developers

Build on your locator from the server or the page.

On the server, account-scoped keys read and write locations, answer nearest-location queries and subscribe to signed webhooks. In the browser, the embedded element takes method calls from your page and dispatches events when visitors act. An MCP server puts the same account within reach of Claude, ChatGPT and other AI assistants.

AI assistants

MCP server

Manage your locator from Claude, ChatGPT, Cursor, or any MCP client. Add locations, restyle the widget and get your embed code by chatting.

Read the docs

REST

Location API

Read, create, update and archive locations over HTTP with a bearer key, for systems that own the data.

Read the docs

REST

Query API

Ask what is near a point and get visible locations back nearest-first, ranked the way the widget ranks them, for a front end of your own.

Read the docs

Push

Webhooks

Signed HTTP calls to your URL when a location is created, updated or deleted, or a visitor sends an enquiry. Retried for two days.

Read the docs

Browser

Widget JavaScript API

Methods on the embedded element: run a search, set filters, open a location or read the state from your own page script.

Read the docs

Browser

Widget events

The events the embedded locator dispatches on the page, for analytics and for wiring the widget into the rest of your site.

Read the docs

Pick the surface by the job

Keep locations in step with a system you own
Write with the Location API and register a webhook, so a change made in the dashboard reaches your system without polling. Location API
Build your own store-finder page or app
Call the Query API with a read-only key. Hidden locations stay hidden, and results come back in the order the widget would show them. Query API
Put a search box in your header or a find-near-me button on a product page
Call methods on the embedded element from your own script. For a search box on a different page, a plain form and URL parameters are enough. Widget JavaScript API
Send locator activity to your analytics
Listen for the widget's browser events and push the ones you need into Google Tag Manager or your own tooling. Widget events
Pass enquiries to a CRM, a sheet or Slack without code
Use Zapier, through the Handled Locator app for Zapier or Zapier's own webhook steps. Both run on the same webhooks and API. Zapier
Keep locations in a spreadsheet or CMS
Connect Google Sheets, Airtable, Webflow CMS or HubSpot as a sync source from the dashboard. No key and no code. Sync sources
Change locations or styling by describing the change
Connect the MCP server to Claude, ChatGPT or another client. Configuration changes are proposed with the exact differences before anything goes live. MCP server

Server side

Location and Query APIs

JSON over HTTPS at /api/v1, with the key sent as a bearer token. Send an address without coordinates and Handled geocodes it; if the lookup fails the location is still created and flagged in the dashboard. The Query API ranks with the same function the widget uses, so a page you build and the locator agree on what is nearest. Hidden locations stay hidden unless you ask for them, and online stockists are left out of distance queries because they have no coordinates.

  • GET /api/v1/locations

    List locations, newest first, with limit, offset, visibility and search.

  • GET /api/v1/locations/:id

    Read one location.

  • POST /api/v1/locations

    Create a location. An address without coordinates is geocoded.

  • PATCH /api/v1/locations/:id

    Change only the fields you send. A null clears a field; an absent one is left alone.

  • DELETE /api/v1/locations/:id

    Take a location off the locator. Soft, so its analytics history survives.

  • GET /api/v1/query

    Visible locations near a point or matching a tag or text, nearest-first with a distance.

Location API reference, errors and examples

Push

Webhooks

Register an HTTPS endpoint and Handled posts the full record to it, signed, when something changes. The signature is an HMAC-SHA256 of the timestamp and the raw body under the endpoint’s secret. Answer with a 2xx quickly and do the work afterwards: a delivery without one is retried for roughly two days, each delivery arrives at least once, and order is not guaranteed. Endpoints can be managed over the API, which is how an integration subscribes itself.

  • location.created

    A location was added, restored from the bin, or created by an import or sync.

  • location.updated

    Any field on a location changed, including tags, custom fields, visibility and photo.

  • location.deleted

    A location was moved to the bin. It can be restored, which fires location.created.

  • lead.created

    A visitor sent an enquiry through the locator's form, after it was routed to a dealer.

Payloads, signature checks and retries

In the browser

Widget JavaScript API

The <biz-locator> element the embed creates has methods your page can call. Calls made before the locator has loaded are queued and replayed in order, so your script never has to wait. Links can carry the same state without any script, and an embed can be locked to a subset of locations with a tag list.

  • search()

    Set the keyword search. No geocoding.

  • searchNear()

    Search near a place name, geocoded as if typed, or near exact coordinates.

  • setFilters()

    Replace the active filters by tag name, slug or id, and report which matched.

  • clearFilters()

    Remove every filter.

  • openLocation()

    Open one location the way a click on its card would.

  • closeLocation()

    Close the open detail pane or popup.

  • locate()

    Ask for the visitor's position and search near it.

  • reset()

    Return to the starting state: no search, no filters.

  • getState()

    Read the current query, place, radius, filters and result count.

  • setLanguage()

    Show the interface in one of the account's languages.

  • getLocations()

    The locations currently listed, in order, with distance when there is a search point.

Method reference and worked examples

In the browser

Widget events

The element dispatches versioned events that bubble out of its shadow root, so a listener on the element or on the document receives them. Payloads carry the mode, counts and location ids, and deliberately omit what the visitor typed, the place it resolved to, their coordinates and any contact details. A search or selection made through a method fires the same events as a visitor’s.

  • handled:ready

    Locations and settings have loaded.

  • handled:search

    A text or near-a-place search ran, with its mode and result count.

  • handled:no-results

    A search or filter state produced nothing.

  • handled:location-selected

    A visitor, or your script, selected a card, marker or online location.

  • handled:directions-clicked

    A visitor opened directions.

  • handled:action-clicked

    A visitor used phone, email, website or a linked custom field.

Payload types and a Tag Manager example

One key, every server surface

The REST API, the Query API, webhook management and the MCP server take the same key and enforce the same rules: your account, your plan’s location allowance, and read-only keys that cannot write. An account owner creates keys under Settings, then API & developer tools. A key is shown once and stored only as a hash, starts with hl_live_, is rate limited per minute with separate read and write budgets, and can be revoked at any time. Claude and ChatGPT need no key: they connect to the MCP server by signing in.

MCP endpoint
https://app.handledlocal.com/api/mcp
Authorization header
Authorization: Bearer hl_live_your_key

The MCP server is included on every plan, including the 7-day trial. The REST API, the Query API and webhooks are Pro and Business features. See pricing.

What these surfaces do not do

  • Categories are created in the dashboard. The API's tag filter matches categories that already exist.
  • Widget settings, branding and labels are not part of the REST API. The dashboard and the MCP server change them.
  • Visitor searches, map moves and clicks stay in the browser as events. They are never sent as webhooks.
  • Handled does not write back into your CRM or other systems. A change reaches them only through a job you write against the webhooks and the API.
  • One account serves one locator, so there is no method for mounting a second, differently configured widget on a page.