fencemaker
HomeUse CasesHow It WorksLive DemoDocsOperations Portal
STEP 01
Get your API key
Go to fencemaker.app/keys and generate a key. Shown once — copy it immediately. Every API call and GPS ping uses this key.
fencemaker.app/keys X-API-Key: <your-api-key>

Step 02 · Create your territories — pick any method

Draw on the map
Open the Territory Editor. Search any city using Mapsi autocomplete, then draw your polygon. No coordinates needed.
fencemaker.app/territories
Bulk upload via CSV
Upload many zones at once via the Bulk tool. Zone names, codes, boundaries — Fencemaker creates all territories in one shot.
fencemaker.app/bulk
Create via API
Programmatically push territories. Optionally use Mapsi Geocoding to convert addresses to coordinates first.
{ } Code
GET mapsi.dev/v1/geocode?text=Koramangala+Bengaluru POST fencemaker.app/api/territories { name, code, hub_id, boundary_geojson }
STEP 03
Territories are live — choose your stream
Your zones are instantly active and queryable. Now choose the integration stream that fits your operation and get your pricing plan.

Choose your integration stream

✓ Selected Stream
Point-in-Polygon API
Is this address
in my zone?
Send a lat/lon or address. Get an instant IN or OUT. Batch thousands of delivery points against your hand-drawn polygon. Perfect for last-mile delivery planning before a run starts.
Draw polygon on map
POST lat/lon or address
Receive { "result": "IN" }
Last-mile zone assignment Serviceability check Batch address validation Zone catchment planning Pincode vs polygon
✓ Selected Stream
Webhook Geofence
Alert me when
they cross the line.
Draw a zone. Connect Slack, Telegram, or a custom URL. When a tracked device's GPS crosses your boundary, Fencemaker fires an alert instantly — to whichever channel you choose. No polling. No manual checks. Pure event-driven operations.
Draw polygon + connect Slack, Telegram, or custom URL
Device GPS crosses boundary
Alert fires to your chosen channel instantly
Slack alerts Telegram bot Custom webhook URL Fleet compliance ETA trigger
▸ Your integration steps
⬡ Point-in-Polygon API
STEP 04
Query a point or batch
Send any lat/lon — delivery address, customer location, vehicle stop. Get back the matching territory instantly. Or send batches of points in one call.
{ } Code
# Single check POST /api/v1/territory X-API-Key: <your-api-key> {"lat": 12.9716, "lon": 77.5946} # Response { matched: true, territory_name: "South Bengaluru", territory_code: "ZONE-A", agent_id: "R-001" } # Batch POST /api/v1/pip/batch {"points": [{"lat": ..., "lon": ...}]}
Synchronous< 10msBatch support
STEP 05
Receive result → feed your process
The response tells you exactly which zone the point belongs to, plus any agent_id you assigned. Feed it straight into dispatch, packing, or your business logic.
Assign riderPack by zoneServiceability check
⚡ Webhook Geofence
STEP 04
Connect your alert channel
In the Alerts dashboard connect Slack (paste an incoming webhook URL), Telegram (link your bot), or a custom URL (any HTTPS endpoint). All three can be active simultaneously. Device registration is optional/track auto-creates devices on first GPS ping.
{ } Channel options
# Option A — Slack incoming webhook # paste https://hooks.slack.com/... in dashboard # Option B — Telegram bot # link bot token + chat ID in dashboard # Option C — custom HTTPS endpoint # set per-territory or org-wide in dashboard # or via API: POST /api/territories { webhook_url: "..." } # (Optional) pre-register a device POST /api/v1/devices X-API-Key: <your-api-key> { device_id: "RIDER-042", label: "Rahul's bike" }
SlackTelegramCustom URLAuto-create on first ping
STEP 05
Send GPS pings from your device
From iOS, Android, or any server — POST a GPS coordinate for each device. One REST call. No SDK required.
{ } Code
POST /api/v1/track X-API-Key: <your-api-key> { device_id: "RIDER-042", lat: 12.9716, lon: 77.5946 }
iOS · Android · RESTNo SDK needed
STEP 06
Alert fires to your channel
The moment a device crosses any zone boundary, Fencemaker delivers to every channel you've connected — a Slack block message, a Telegram notification, and/or an HTTP POST to your endpoint. Automatic retries on failure. Entry, exit, or both.
{ } Custom URL payload
{ event: "entered", device_id: "RIDER-042", territory_code: "ZONE-A", territory_name: "South Bengaluru", lat: 12.9716, lon: 77.5946, timestamp: "2026-03-09T..." } # Slack → rich block message with Google Maps link # Telegram → formatted message via your bot
Slack block messageTelegram notificationHTTP POSTentered / exited
Zone assigned. Process triggered.
Every address or coordinate is instantly matched to a territory — before dispatch, in bulk, on demand.
✦ Optional — works with both streams
STEP 7 · OPTIONAL
Embed a live map in your own product
Fencemaker exposes a tile proxy and a territories GeoJSON endpoint — your customers need only their Fencemaker API key to render a full live map.

Tiles are proxied server-side via Mapsi's CDN (our CDN). Overlay zone polygons directly from Fencemaker. Poll your backend and plot each device as a moving dot.
GET /api/v1/map/tiles/{z}/{x}/{y}
GET /api/v1/map/territories
MapLibre GLOne API keyDevice dots
① Init map
{ } Code
const map = new maplibregl.Map({ container: 'map', style: { version: 8, sources: { 'fm': { type: 'vector', tiles: ['https://fencemaker.app/api/v1/map/tiles/{z}/{x}/{y}'], maxzoom: 15 }}}, transformRequest: (url) => ({ url, headers: { 'X-API-Key': FM_KEY } }) });
② Load zone polygons
{ } Code
const zones = await fetch( 'https://fencemaker.app/api/v1/map/territories', { headers: { 'X-API-Key': FM_KEY } } ).then(r => r.json()); map.addSource('zones', { type: 'geojson', data: zones }); map.addLayer({ id: 'zones-fill', type: 'fill', source: 'zones', paint: { 'fill-opacity': 0.15 } });
③ Plot live device dots (poll every 8s)
{ } Code
async function refresh() { const pings = await fetch('/your-api/latest-pings').then(r => r.json()); map.getSource('devices').setData({ type: 'FeatureCollection', features: pings.map(p => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [p.lon, p.lat] }, properties: { id: p.device_id } })) }); } setInterval(refresh, 8000);
Tile proxy: /api/v1/map/tiles/{z}/{x}/{y} forwards to Mapsi's CDN server-side — provider invisible to clients. · Territories: /api/v1/map/territories returns GeoJSON for MapLibre. · Devices: your backend owns position state — poll and render as dots.
Stream
Point-in-Polygon API
PiP
WH