# Connections

Source: https://solidhooks.com/docs/connections

> Route events from one source to one destination, filter by event type, and fan one source out to many destinations.

A connection routes one source to one destination. Nothing is delivered until a connection exists, because the source only receives and stores events, and the destination only describes where to send them.

Connection IDs start with `conn_`.

## How it works

When an event is accepted, SolidHooks looks at every connection on that source and keeps the ones that are active and whose filter matches the event. Each match creates one delivery to that connection's destination.

To fan one source out to several destinations, create several connections on the same source. To feed one destination from several sources, create a connection from each. Each connection has its own name and filter.

A connection is active when it is enabled, its destination is enabled and, for a private destination, its connector is enabled.

Billing counts deliveries, so every matching connection is one billable delivery. An event that matches three connections is three deliveries. Automatic retries are free. See [Plans](https://solidhooks.com/docs/plans).

## Fields

| Field           | Notes                                                |
| --------------- | ---------------------------------------------------- |
| `name`          | Required, up to 100 characters.                      |
| `sourceId`      | The source to connect from. Fixed after creation.    |
| `destinationId` | The destination to connect to. Fixed after creation. |
| `filterRules`   | Optional. `{ "eventTypes": ["..."] }`.               |
| `isDisabled`    | Set on update to pause or resume the connection.     |

A connection's route cannot be changed. To send the same events somewhere else, create a new connection. On update you can change `name`, `filterRules` and `isDisabled`.

## Filter by event type

`filterRules.eventTypes` is an allowlist of event types. An event is delivered through the connection only if its type is in the list.

* Omit `filterRules`, pass `null` or `{}`, or send an empty `eventTypes` array to forward every event.
* The comparison ignores case, so `Billing@Supplier.example` matches `billing@supplier.example`.
* Types the source never sends are allowed in the list. They simply never match.

The event type comes from the source, not from the connection. It is read from the source's `eventTypeField`, a dot-path such as `headers.x-github-event` or `body.type`, when the event arrives, and stored with the event. Known providers set a default path for you. See [Sources](https://solidhooks.com/docs/sources).

> **A source with no event type field ignores filters**
>
> If a source has no `eventTypeField`, its events have no type to match. In that case an allowlist on a connection is inert and every event is delivered. The dashboard warns about this when you create or edit a filtered connection.

On an email source, the type is the field you chose (`body.from` or `body.subject`), falling back to `email.received`.

## Event status and filtering

The event's `status` records what routing did with it:

| Status      | Meaning                                                                                  |
| ----------- | ---------------------------------------------------------------------------------------- |
| `received`  | At least one connection matched and the event was dispatched.                            |
| `filtered`  | The source has active connections, but their event-type filters all excluded this event. |
| `unmatched` | The source has no active connections.                                                    |

Filtered and unmatched events are still stored, so you can find them later and [replay](https://solidhooks.com/docs/replay) them once a connection exists or a filter is widened. Because a disabled connection, or one whose destination is disabled, does not count as active, an event can read `unmatched` when connections exist but are all paused.

If you narrow a filter after a delivery was queued, the delivery is checked again when it runs. If the event type is no longer allowed, the delivery ends as `filtered` and nothing is sent. See [Deliveries](https://solidhooks.com/docs/deliveries).

## Create a connection

**API**

```bash
curl -s "$API/v1/connections" \
  -H "authorization: Bearer $SDHK_KEY" \
  -H 'content-type: application/json' \
  -d '{
    "name": "GitHub to My app",
    "sourceId": "src_...",
    "destinationId": "dest_...",
    "filterRules": { "eventTypes": ["push", "pull_request"] }
  }'
```

List connections with `GET /v1/connections`, filtered by `sourceId` or `destinationId`. Update with `PATCH /v1/connections/{id}`:

```bash
curl -s -X PATCH "$API/v1/connections/conn_..." \
  -H "authorization: Bearer $SDHK_KEY" \
  -H 'content-type: application/json' \
  -d '{ "data": { "filterRules": { "eventTypes": ["push"] } } }'
```

**Dashboard**

1. Open **Sources**, pick the source and open its **Connections**.
2. Click **New Connection**.
3. Choose the destination. You can search by name or URL.
4. Name the connection and, optionally, add the event types it should carry. Leave the list empty to receive all event types.
5. Click **Create connection**.

To edit a connection, open it and use its settings. **General** holds the name and **Filters** holds the event-type list. The destination is shown but cannot be changed.

## Pause and resume

Setting `isDisabled` to `true` pauses a connection. New events stop being routed through it. A delivery already queued through a paused connection is recorded as `skipped` rather than sent.

**API**

```bash
curl -s -X PATCH "$API/v1/connections/conn_..." \
  -H "authorization: Bearer $SDHK_KEY" \
  -H 'content-type: application/json' \
  -d '{ "data": { "isDisabled": true } }'
```

Send `"isDisabled": false` to resume.

**Dashboard**

On the source's **Connections** list, use the pause or resume control on the connection's row, or **Pause** and **Resume** on its page. The list shows **Paused** or **Active**.

## Delete a connection

`DELETE /v1/connections/{id}` removes the route. Events stop being routed through it. Deleting needs a key scoped `connection: read & write`; an unscoped key cannot delete. In the dashboard, use the delete action on the connection and confirm.

Delete every connection pointing at a destination before you can delete the destination.

## Next steps

* [Sources](https://solidhooks.com/docs/sources) — set the `eventTypeField` that filters read
* [Destinations](https://solidhooks.com/docs/destinations) — define where deliveries go
* [Deliveries](https://solidhooks.com/docs/deliveries) — see what each connection produced
* [Replay](https://solidhooks.com/docs/replay) — re-run an event through its connections

API reference: [Connections](https://api.solidhooks.com/v1/#tag/connections).