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

# Sinks

> Deliver join and window results to webhooks, Kafka, SSE streams, or local databases.

# Sinks

Sinks are destinations for join and window results. LiteJoin evaluates your SQL queries and forwards matching results to one or more configured sinks.

## HTTP Webhook

Sends results as JSON `POST` requests to a URL.

```yaml theme={null}
sinks:
  - type: http
    name: webhook-out
    config:
      url: "http://localhost:9000/webhook"
      timeout: "30s"
```

| Field     | Type     | Default  | Description                     |
| --------- | -------- | -------- | ------------------------------- |
| `url`     | string   | required | Webhook URL to POST results to. |
| `timeout` | duration | `30s`    | Request timeout.                |

Results are sent as JSON in the request body.

## Kafka

Produces results as messages to a Kafka topic.

```yaml theme={null}
sinks:
  - type: kafka
    name: kafka-out
    config:
      brokers: "localhost:9092"
      topic: "joined-events"
```

| Field     | Type   | Default  | Description                       |
| --------- | ------ | -------- | --------------------------------- |
| `brokers` | string | required | Comma-separated broker addresses. |
| `topic`   | string | required | Target Kafka topic.               |

## SSE (Server-Sent Events)

Streams results to browser clients via Server-Sent Events. Ideal for real-time dashboards and UIs.

```yaml theme={null}
sinks:
  - type: sse
    name: dashboard
    config:
      addr: ":9100"
```

| Field  | Type   | Default  | Description           |
| ------ | ------ | -------- | --------------------- |
| `addr` | string | required | Address to listen on. |

### Endpoints

The SSE sink exposes three HTTP endpoints:

| Endpoint     | Method | Description                                                                              |
| ------------ | ------ | ---------------------------------------------------------------------------------------- |
| `/subscribe` | GET    | Opens an SSE stream. Use `?join=name` to filter by join or `?join=*` for all.            |
| `/snapshot`  | GET    | Returns a JSON snapshot of current results. See [Snapshot API](/pipelines/snapshot-api). |
| `/health`    | GET    | Health check — returns `{"status": "ok"}`.                                               |

### Browser Example

```javascript theme={null}
const es = new EventSource('http://localhost:9100/subscribe?join=*');

es.addEventListener('join_result', (event) => {
  const result = JSON.parse(event.data);
  console.log(result.query, result.key, result.rows);
});
```

### Replay on Connect

Add `?replay=true` to receive a snapshot of current results as SSE events before switching to live streaming:

```javascript theme={null}
const es = new EventSource('http://localhost:9100/subscribe?join=*&replay=true');
```

Replay events include `"_replay": true` so your client can distinguish initial state from live updates.

## SQLite

Writes results to a local SQLite database for querying by external apps.

```yaml theme={null}
sinks:
  - type: sqlite
    name: local-db
    config:
      path: "./output/results.db"
```

| Field  | Type   | Default  | Description                       |
| ------ | ------ | -------- | --------------------------------- |
| `path` | string | required | Path to the SQLite database file. |

## Routing Joins to Sinks

Each join or window specifies its target sink by name:

```yaml theme={null}
joins:
  - name: order-enrichment
    query: |
      SELECT ...
    sink: webhook-out    # ← references the sink name

sinks:
  - type: http
    name: webhook-out    # ← matched by name
    config:
      url: "http://example.com/webhook"
```

Multiple joins can route to the same sink, and you can configure multiple sinks of different types.
