> ## 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.

# Geofences API

> Create, manage, and check geofences for location-based decisioning triggers.

The Geofences API provides CRUD operations for geofence definitions and a real-time check endpoint that determines which geofences a given coordinate falls within.

<Info>
  See the [Geofencing feature page](/studio/geofencing) for business context, integration patterns, and configuration guidance.
</Info>

## Base Path

```
/api/v1/geofences          # CRUD operations
/api/v1/geofences/check    # Location check
```

***

## GET /api/v1/geofences

List all geofences for the current tenant, ordered by creation date (newest first).

**Roles:** admin, editor, viewer

### Response `200`

```json theme={null}
{
  "data": [
    {
      "id": "gf_001",
      "tenantId": "t_001",
      "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",
      "createdAt": "2026-04-01T10:00:00.000Z",
      "updatedAt": "2026-04-01T10:00:00.000Z"
    }
  ]
}
```

### Response Fields

| Field          | Type            | Description                               |
| -------------- | --------------- | ----------------------------------------- |
| `id`           | string          | Unique geofence identifier                |
| `tenantId`     | string          | Tenant identifier                         |
| `name`         | string          | Human-readable name                       |
| `description`  | string          | Optional description                      |
| `latitude`     | number          | Center latitude                           |
| `longitude`    | number          | Center longitude                          |
| `radiusMeters` | integer         | Radius in meters                          |
| `triggerOn`    | string          | Trigger type: `enter`, `exit`, or `dwell` |
| `dwellMinutes` | integer or null | Minutes required for dwell triggers       |
| `cooldownMs`   | integer         | Cooldown period in milliseconds           |
| `action`       | object          | Action payload to execute on trigger      |
| `status`       | string          | `active` or `inactive`                    |
| `createdAt`    | string          | ISO 8601 creation timestamp               |
| `updatedAt`    | string          | ISO 8601 last update timestamp            |

### Example

```bash theme={null}
curl https://playground.kaireonai.com/api/v1/geofences \
  -H "X-Tenant-Id: my-tenant" \
  -H "Authorization: Bearer <token>"
```

***

## POST /api/v1/geofences

Create a new geofence.

**Roles:** admin, editor

### Request Body

| Field          | Type    | Required | Description                                   |
| -------------- | ------- | -------- | --------------------------------------------- |
| `name`         | string  | Yes      | Geofence name                                 |
| `description`  | string  | No       | Optional description                          |
| `latitude`     | number  | Yes      | Center latitude (-90 to 90)                   |
| `longitude`    | number  | Yes      | Center longitude (-180 to 180)                |
| `radiusMeters` | integer | No       | Radius in meters. Default: `500`              |
| `triggerOn`    | string  | No       | `enter`, `exit`, or `dwell`. Default: `enter` |
| `dwellMinutes` | integer | No       | Minutes for dwell triggers                    |
| `cooldownMs`   | integer | No       | Cooldown in ms. Default: `86400000` (24h)     |
| `action`       | object  | No       | Action payload                                |
| `status`       | string  | No       | `active` or `inactive`. Default: `active`     |

### Response `201`

Returns the created geofence object (same shape as GET response items).

### Example

```bash theme={null}
curl -X POST https://playground.kaireonai.com/api/v1/geofences \
  -H "X-Tenant-Id: my-tenant" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name": "Airport Terminal",
    "latitude": 47.4502,
    "longitude": -122.3088,
    "radiusMeters": 1000,
    "triggerOn": "dwell",
    "dwellMinutes": 30,
    "cooldownMs": 43200000,
    "action": {
      "type": "recommend",
      "decisionFlowId": "df_travel",
      "channel": "push"
    }
  }'
```

***

## PUT /api/v1/geofences

Update an existing geofence. The request body must include the `id` field. All other fields are optional and only provided fields are updated.

**Roles:** admin, editor

### Request Body

| Field          | Type    | Required | Description            |
| -------------- | ------- | -------- | ---------------------- |
| `id`           | string  | Yes      | Geofence ID to update  |
| `name`         | string  | No       | Updated name           |
| `description`  | string  | No       | Updated description    |
| `latitude`     | number  | No       | Updated latitude       |
| `longitude`    | number  | No       | Updated longitude      |
| `radiusMeters` | integer | No       | Updated radius         |
| `triggerOn`    | string  | No       | Updated trigger type   |
| `dwellMinutes` | integer | No       | Updated dwell time     |
| `cooldownMs`   | integer | No       | Updated cooldown       |
| `action`       | object  | No       | Updated action payload |
| `status`       | string  | No       | Updated status         |

### Response `200`

Returns the updated geofence object.

### Example

```bash theme={null}
curl -X PUT https://playground.kaireonai.com/api/v1/geofences \
  -H "X-Tenant-Id: my-tenant" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "gf_001",
    "radiusMeters": 300,
    "status": "inactive"
  }'
```

***

## DELETE /api/v1/geofences

Permanently delete a geofence.

**Roles:** admin

### Query Parameters

| Parameter | Type   | Required | Description           |
| --------- | ------ | -------- | --------------------- |
| `id`      | string | Yes      | Geofence ID to delete |

### Response `200`

```json theme={null}
{
  "deleted": true
}
```

### Example

```bash theme={null}
curl -X DELETE "https://playground.kaireonai.com/api/v1/geofences?id=gf_001" \
  -H "X-Tenant-Id: my-tenant" \
  -H "Authorization: Bearer <token>"
```

***

## POST /api/v1/geofences/check

Check which active geofences a given coordinate falls within. Uses the Haversine formula for distance calculation.

**Roles:** admin, editor, viewer

### Request Body

| Field        | Type   | Required | Description                                                             |
| ------------ | ------ | -------- | ----------------------------------------------------------------------- |
| `latitude`   | number | Yes      | Current latitude                                                        |
| `longitude`  | number | Yes      | Current longitude                                                       |
| `customerId` | string | No       | Optional customer identifier (returned in the response for correlation) |

### Response `200`

```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"
    }
  ]
}
```

### Match Fields

| Field          | Type    | Description                                                   |
| -------------- | ------- | ------------------------------------------------------------- |
| `geofenceId`   | string  | ID of the matched geofence                                    |
| `geofenceName` | string  | Name of the matched geofence                                  |
| `distance`     | integer | Distance in meters from the coordinate to the geofence center |
| `radiusMeters` | integer | Radius of the geofence                                        |
| `action`       | object  | Action payload configured on this geofence                    |
| `triggerOn`    | string  | Trigger type (`enter`, `exit`, `dwell`)                       |

### Example

```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
  }'
```

***

## Error Codes

| Status | Code         | Description                                                                                                                    |
| ------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `400`  | Bad Request  | Missing required fields (`name`, `latitude`, `longitude` for create; `id` for update/delete; `latitude`/`longitude` for check) |
| `401`  | Unauthorized | Missing or invalid authentication                                                                                              |
| `403`  | Forbidden    | Insufficient role for this operation                                                                                           |
| `404`  | Not Found    | Geofence ID not found (update/delete)                                                                                          |
| `500`  | Server Error | Internal error                                                                                                                 |

***

## See Also

* [Geofencing Feature Guide](/studio/geofencing)
* [Event Ingestion](/api-reference/events-ingest)
* [Triggers](/api-reference/triggers)
