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

# Signals API

> POST, GET, DELETE signals and subscribe to the live SSE stream.

## Endpoints

| Method   | Path                 | Description            |
| -------- | -------------------- | ---------------------- |
| `POST`   | `/v1/signals`        | Create a signal        |
| `GET`    | `/v1/signals`        | List persisted signals |
| `DELETE` | `/v1/signals/beacon` | Stop active beacon     |
| `GET`    | `/v1/signals/stream` | SSE live stream        |

***

## POST /v1/signals

Create a signal. `beacon` type is broadcast-only (not persisted). All others are saved and queryable.

**Body**

```json theme={null}
{
  "type": "beacon | capture | note | checkin | alert",
  "lat": 35.4676,
  "lng": -97.5164,
  "accuracy": 12.5,
  "note": "Optional text",
  "image_url": "https://...",
  "ticket_id": 42,
  "org_id": 3,
  "meta": {}
}
```

| Field       | Type   | Required | Description                           |
| ----------- | ------ | -------- | ------------------------------------- |
| `type`      | string | **yes**  | Signal type                           |
| `lat`       | number | no       | Latitude                              |
| `lng`       | number | no       | Longitude                             |
| `accuracy`  | number | no       | GPS accuracy in meters                |
| `note`      | string | no       | Text content (required for `alert`)   |
| `image_url` | string | no       | Image URL (for `capture`)             |
| `ticket_id` | number | no       | Link to an incident                   |
| `org_id`    | number | no       | Target org — defaults to primary org  |
| `meta`      | object | no       | Arbitrary metadata (e.g. `device_id`) |

**Response `201`**

```json theme={null}
{
  "Id": 99,
  "user_id": 42,
  "org_id": 3,
  "type": "note",
  "lat": 35.4676,
  "lng": -97.5164,
  "note": "On site.",
  "created_at": "2026-03-15T07:00:00Z",
  "user_name": "Jason Johnson"
}
```

<Note>
  `alert` signals trigger push notifications to all members of the target org.
  `beacon` signals return the same shape but `Id` will be `null` — they are not persisted.
</Note>

***

## GET /v1/signals

List persisted signals for your orgs. Does not include `beacon` signals.

**Query params**

| Param    | Default | Description    |
| -------- | ------- | -------------- |
| `limit`  | `50`    | Max results    |
| `page`   | `1`     | Page number    |
| `type`   | —       | Filter by type |
| `org_id` | —       | Filter by org  |

***

## DELETE /v1/signals/beacon

Stop the active beacon for the current device. Broadcasts a `beacon_off` event to the org SSE stream so the War Room removes the device dot.

Pass `device_id` in the body to identify the specific device:

```json theme={null}
{ "device_id": "dev-4f2a1b-c3d4e5f6" }
```

**Response `200`**

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

***

## GET /v1/signals/stream

SSE live stream of all signals for your orgs. Keep-alive with 25s heartbeat comments.

```bash theme={null}
curl -N https://schedkit.net/v1/signals/stream \
  -H "x-api-key: $SCHEDKIT_KEY"
```

**Event types**

| Event            | Trigger                   |
| ---------------- | ------------------------- |
| `signal.beacon`  | Operator GPS ping         |
| `signal.capture` | Photo captured in field   |
| `signal.note`    | Note posted               |
| `signal.checkin` | Manual check-in           |
| `signal.alert`   | High-priority alert fired |
| `beacon_off`     | Operator beacon stopped   |

**Example stream**

```
data: {"type":"connected","org_ids":[3]}

: heartbeat

data: {"type":"signal.beacon","payload":{"user_id":42,"lat":35.4676,"lng":-97.5164,"accuracy":8,"meta":{"device_id":"dev-4f2a-c3d4"},"created_at":"2026-03-15T07:30:00Z","user_name":"Jason Johnson","org_id":3}}

data: {"type":"signal.alert","payload":{"Id":7,"note":"Unit 3 unresponsive","user_id":42,"org_id":3,"created_at":"2026-03-15T07:31:00Z"}}

data: {"type":"beacon_off","payload":{"device_id":"dev-4f2a-c3d4","user_id":42,"org_id":3}}
```
