Location & Store Marketing
Tie engagement to the physical store — measure real, member-keyed store visits, target by store or region, and re-engage members who came near a store. Built privacy-first: consent + Global Privacy Control, fail-closed, no raw coordinates stored.
Capabilities
Deterministic store visit
A QR check-in or in-store redeem fires a member-keyed, DB-deduplicated store-visit event. No device location needed. With a randomized holdout, you measure true incremental lift.
Store / region targeting
Target members by their attributed store or region for location-relevant offers — first-party, no device tracking.
Geofence endpoints + triggers
nearby-stores + geofence-event, with consent + GPC fail-closed and near_store / store_dwell automation triggers wired in.
On-device proximity detection
Background geofencing ships with the FlashLocation package (CoreLocation / Play Services, no Radar dependency) — download it from the Mobile SDK and integrate it into your app.
Start here: deterministic store visits
// No device location required. A QR check-in or an in-store coupon redeem fires a
// member-keyed store-visit event, deduplicated at the database — the cleaner,
// privacy-safe signal for store-driven campaigns.
//
// QR check-in / in-store redeem → store_visit_event (member-keyed, DB-deduped)
//
// Pair it with a randomized holdout to measure INCREMENTAL visits your campaign
// actually caused — not self-reported footfall.Geofence endpoints
Callable from a signed-in member session. The on-device piece that calls them — background geofence monitoring — ships with the FlashLocation package in the Mobile SDK; download it and integrate it into your app.
1. Get the nearest store geofences to monitor
// The device reports its current location; the server returns the ≤20 NEAREST store
// geofences for it to monitor (server-curated to fit iOS's 20-region limit). The
// lat/lng is used transiently to rank stores and is NOT persisted.
POST /api/v2/lbs/nearby-stores
Content-Type: application/json
{ "lat": 40.71, "lng": -74.00, "limit": 20 }
// → 200 { "geofences": [
// { "storeId": "…", "name": "…", "lat": …, "lng": …, "distanceMeters": … }
// ] }
//
// FAIL-CLOSED: no precise_location_consent, or a Global Privacy Control signal
// present → { "geofences": [] } (empty set, no error).2. Report a geofence transition
// When the device crosses a monitored geofence, report the transition. This fires
// the near_store / store_dwell automation triggers server-side.
POST /api/v2/lbs/geofence-event
Content-Type: application/json
{ "storeId": "<uuid>", "eventType": "enter" } // "enter" | "dwell"
// → 200 { "recorded": true }
//
// FAIL-CLOSED privacy gate:
// GPC signal present → { "recorded": false, "reason": "gpc" }
// no precise_location_consent → { "recorded": false, "reason": "no_consent" }
// Flash records only the derived enter/dwell event — never the device's coordinates.Privacy by construction
Precise location is gated by explicit precise_location_consent AND the absence of a Global Privacy Control signal — both checked, fail-closed.
Flash stores only derived enter / dwell events. Raw device coordinates are never persisted; the lat/lng you send to nearby-stores is used transiently to rank stores and discarded.
Consent is withdrawable one-tap with no penalty; withdrawal takes effect immediately on the next call.