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

# Connectors

> Connect an outside source, sync it on demand, and disconnect it cleanly.

## What this family does

Connectors are the managed side of ingestion: instead of pushing content yourself, you authorize a provider once and Exo keeps pulling. GitHub is the only provider in v1.

Connecting returns a URL to send the user to. The install is finalized by the provider's callback. Syncing enqueues one backfill job per repository and returns the ids of the jobs it newly enqueued.

## Routes

| Method   | Path                                                                           | Scope   | What it does                    |
| -------- | ------------------------------------------------------------------------------ | ------- | ------------------------------- |
| `GET`    | [`/v1/connectors`](/api-reference/connectors/list-connectors)                  | `read`  | List connectors                 |
| `DELETE` | [`/v1/connectors/{connector}`](/api-reference/connectors/disconnect-connector) | `write` | Disconnect a connector          |
| `POST`   | [`/v1/connectors/{connector}`](/api-reference/connectors/connect-connector)    | `write` | Begin a connector connect flow  |
| `POST`   | [`/v1/connectors/{connector}/sync`](/api-reference/connectors/sync-connector)  | `write` | Trigger a manual connector sync |

## The shape of a call

List connectors.

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  curl https://api.get-exo.com/v1/connectors \
    -H "X-Exo-API-Key: $EXO_KEY"
  ```

  ```python Python theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  import httpx

  response = httpx.get(
      "https://api.get-exo.com/v1/connectors",
      headers={"X-Exo-API-Key": EXO_KEY},
  )
  connectors = response.json()["data"]
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  const response = await fetch("https://api.get-exo.com/v1/connectors", {
    headers: { "X-Exo-API-Key": process.env.EXO_KEY! },
  });
  const { data } = await response.json();
  ```
</CodeGroup>

The response:

```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
{
  "data": [
    { "provider": "github", "id": null, "status": "not_connected", "repos": null }
  ]
}
```

## Traps

**`not_connected` is a status, not an error.** An organization that has never connected a provider still gets a provider stub back, with `status: "not_connected"` and no `id`, so the provider stays discoverable. The connector error codes are `connector_not_found` and `connector_not_syncable`.

**Disconnect is a tombstone.** It marks the installation disconnected and stops syncing. It is idempotent, and reconnecting means starting the connect flow again.

**Sync is safe to repeat.** A backfill already in flight is absorbed by the queue, and the worker deduplicates content at ingest.

## Related

<Columns cols={2}>
  <Card title="API reference" icon="book-open" href="/api-reference/overview">
    Base URL, authentication, and the conventions every route shares.
  </Card>

  <Card title="Errors" icon="circle-alert" href="/platform/errors">
    The problem envelope and the full code catalogue.
  </Card>
</Columns>
