> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Geofencing & Location Triggers

> Define geographic boundaries and trigger real-time actions when customers enter, exit, or dwell in a location.

Geofencing lets you define circular geographic boundaries around physical locations (stores, events, competitor sites) and trigger actions when a customer's device reports a location inside that boundary. Combined with the event ingestion pipeline and decision flows, geofences enable hyper-local, context-aware marketing.

<Info>
  Geofences use the Haversine formula for accurate distance calculations on Earth's surface. All radius values are in meters.
</Info>

***

## Business Value

| Scenario                 | How Geofencing Helps                                                                  |
| ------------------------ | ------------------------------------------------------------------------------------- |
| **Store proximity**      | Push a mobile offer when a customer is within 200m of a retail location               |
| **Event marketing**      | Trigger welcome messages at a conference venue boundary                               |
| **Competitor conquest**  | Detect when customers visit competitor locations and follow up with a retention offer |
| **Dwell-based triggers** | Send a survey after a customer spends 15+ minutes in-store                            |

***

## How It Works

<Steps>
  <Step title="Define geofences">
    Create geofence records with a center point (latitude/longitude), radius in meters, and trigger configuration (enter, exit, or dwell).
  </Step>

  <Step title="Receive location updates">
    Your mobile app or IoT system sends location updates to the Geofence Check API with the customer's coordinates.
  </Step>

  <Step title="Match against active geofences">
    The engine calculates the Haversine distance from the customer's position to each geofence center and returns all matches where the distance is within the radius.
  </Step>

  <Step title="Execute actions">
    Each matched geofence includes an `action` payload that your application uses to trigger the appropriate response (e.g., call the Recommend API, send a push notification, enroll in a journey).
  </Step>
</Steps>

***

## Configuration

### Creating a Geofence

```bash theme={null}
curl -X POST https://playground.kaireonai.com/api/v1/geofences \
  -H "X-Tenant-Id: my-tenant" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Downtown Flagship Store",
    "description": "200m radius around main retail location",
    "latitude": 47.6062,
    "longitude": -122.3321,
    "radiusMeters": 200,
    "triggerOn": "enter",
    "dwellMinutes": null,
    "cooldownMs": 86400000,
    "action": {
      "type": "recommend",
      "decisionFlowId": "df_store_promo",
      "channel": "push"
    },
    "status": "active"
  }'
```

### Geofence Fields

| Field          | Type    | Required | Description                                                                                        |
| -------------- | ------- | -------- | -------------------------------------------------------------------------------------------------- |
| `name`         | string  | Yes      | Human-readable name for the geofence                                                               |
| `description`  | string  | No       | Optional description                                                                               |
| `latitude`     | number  | Yes      | Center point latitude (-90 to 90)                                                                  |
| `longitude`    | number  | Yes      | Center point longitude (-180 to 180)                                                               |
| `radiusMeters` | integer | No       | Radius in meters. Default: `500`                                                                   |
| `triggerOn`    | string  | No       | When to fire: `enter`, `exit`, or `dwell`. Default: `enter`                                        |
| `dwellMinutes` | integer | No       | Minutes the customer must remain inside before triggering (only for `dwell` type)                  |
| `cooldownMs`   | integer | No       | Milliseconds before the same customer can re-trigger this geofence. Default: `86400000` (24 hours) |
| `action`       | object  | No       | Arbitrary JSON payload describing the action to take on trigger                                    |
| `status`       | string  | No       | `active` or `inactive`. Default: `active`                                                          |

### Trigger Types

| Type    | Behavior                                                                     |
| ------- | ---------------------------------------------------------------------------- |
| `enter` | Fires when a customer's location first falls within the radius               |
| `exit`  | Fires when a customer's location moves outside the radius after being inside |
| `dwell` | Fires when a customer remains inside the radius for at least `dwellMinutes`  |

<Warning>
  Geofence checks are stateless on the server side. Your mobile app is responsible for tracking enter/exit transitions and dwell time. The Check API tells you which geofences match a given coordinate pair at a point in time.
</Warning>

***

## Checking Location

To check whether a customer is inside any active geofences:

```bash theme={null}
curl -X POST https://playground.kaireonai.com/api/v1/geofences/check \
  -H "X-Tenant-Id: my-tenant" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "CUST-001",
    "latitude": 47.6065,
    "longitude": -122.3325
  }'
```

### Response

```json theme={null}
{
  "customerId": "CUST-001",
  "latitude": 47.6065,
  "longitude": -122.3325,
  "matchCount": 1,
  "matches": [
    {
      "geofenceId": "gf_001",
      "geofenceName": "Downtown Flagship Store",
      "distance": 45,
      "radiusMeters": 200,
      "action": {
        "type": "recommend",
        "decisionFlowId": "df_store_promo",
        "channel": "push"
      },
      "triggerOn": "enter"
    }
  ]
}
```

***

## Integration with Decision Flows

A common pattern is to chain geofence detection with a Recommend API call:

1. Mobile app detects location change, calls `/api/v1/geofences/check`
2. If matches are returned, extract the `decisionFlowId` from the action payload
3. Call `/api/v1/recommend` with the decision flow ID and customer context
4. Display the personalized offer via push notification or in-app message

This keeps the geofence lightweight (just location matching) while the decision flow handles all business logic, scoring, and personalization.

***

## API Reference

See the full [Geofences API Reference](/api-reference/geofences) for all CRUD endpoints, the check endpoint, field descriptions, and error codes.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Geofences API" icon="code" href="/api-reference/geofences">
    Full CRUD and check endpoint documentation.
  </Card>

  <Card title="Event Ingestion" icon="bolt" href="/api-reference/events">
    Feed location events into the trigger engine.
  </Card>

  <Card title="Triggers" icon="bell" href="/studio/triggers">
    Configure rules that fire actions based on events.
  </Card>

  <Card title="Channels" icon="paper-plane" href="/studio/channels">
    Set up push notification delivery via Firebase or webhook adapters.
  </Card>
</CardGroup>
