> ## Documentation Index
> Fetch the complete documentation index at: https://cortex-e852fafe-t3code-rewrite-docs-declutter.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Connectors

> How HydraDB connectors continuously sync external app data into your database.

Connectors bring external app data into HydraDB automatically. Instead of ingesting documents yourself, you connect an account once, choose which resources to sync, and HydraDB keeps their content synced into your database as searchable [app sources](/essentials/v2/app-sources).

***

## How it works

Setting up a connector takes three calls, made once:

1. **Create:** `POST /connectors` stores the credentials for one provider account.
2. **Discover:** `GET /connectors/{id}/discover` lists what those credentials can reach: Slack channels, GitHub repositories, Linear teams and projects, Notion databases and pages, Supabase tables, and so on.
3. **Configure:** `POST /connectors/{id}/configure` activates the resources you choose and starts the first sync.

From then on, HydraDB syncs every active resource on a schedule (every hour by default). Each sync fetches only what changed since the last one and ingests it as app sources. Call `POST /connectors/{id}/sync` when you need data sooner, and `GET /connectors/{id}/status` to check that everything is working.

### Authentication

All connector endpoints use the same API key as the rest of HydraDB:

```bash theme={"dark"}
Authorization: Bearer $HYDRA_DB_API_KEY
API-Version: 2
```

### Creating a connector

```bash theme={"dark"}
curl -X POST 'https://api.hydradb.com/connectors' \
  -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
  -H "API-Version: 2" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "slack",
    "name": "acme-engineering",
    "database": "acme_corp",
    "collection": "engineering",
    "provider_account_scope": "T12345ACME",
    "credentials": { "access_token": "xoxp-..." }
  }'
```

* `provider`: a provider id from [List Connector Providers](/api-reference/v2/endpoint/list-connector-providers).
* `database` and `collection`: where the synced data goes. Individual resources can route to a different collection.
* `credentials`: the provider's credentials. Their shape is the provider's `credential_schema` from [List Connector Providers](/api-reference/v2/endpoint/list-connector-providers), called with `?id={provider}`.
* `provider_account_scope`: identifies the external account. See below.
* Optional: `name`, `custom_instructions` and `sync_interval_seconds`. `custom_instructions` and `sync_interval_seconds` can be changed later; `name` cannot.

### provider\_account\_scope

`provider_account_scope` tells HydraDB which external account a connector belongs to. It is part of the deduplication key of every object the connector syncs, so objects from two different accounts do not overwrite each other.

What to use for each provider:

* **Slack:** the workspace id, which starts with `T`. Open Slack in a browser: it is the `T...` segment of `app.slack.com/client/T.../`.
* **GitHub:** the organization or user login from your GitHub URL, as in `github.com/my-github-org`.
* **Linear:** the workspace name shown in Settings, under Workspace.
* **Notion:** the workspace name shown at the top of Settings, under Workspace.
* **Gmail:** leave it empty. To scope queries to one mailbox, filter on `account_email` in `additional_metadata` instead.

If you connect two accounts of the same provider into the same database and collection, give each connector a distinct `provider_account_scope`. Otherwise objects from the two accounts that happen to share an external id can overwrite each other.

### Configuring resources

After creating the connector, activate the resources you want to sync:

```bash theme={"dark"}
curl -X POST 'https://api.hydradb.com/connectors/{id}/configure' \
  -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
  -H "API-Version: 2" \
  -H "Content-Type: application/json" \
  -d '{
    "lookback_days": 30,
    "resources": [
      {
        "resource_id": "C_GENERAL",
        "resource_type": "channel",
        "name": "general",
        "collection": "all-hands",
        "metadata": { "department": "all-hands" },
        "additional_metadata": { "internal_label": "general-slack" }
      },
      {
        "resource_id": "C_ENG",
        "resource_type": "channel",
        "name": "engineering",
        "collection": "engineering",
        "metadata": { "department": "engineering" }
      }
    ]
  }'
```

`lookback_days` sets how much history the first sync fetches (default `30`). After that, each sync fetches only what is new.

Besides `resource_id`, `resource_type` and `name`, each resource can carry:

* `collection` (or `database`): routes this resource's objects somewhere other than the connector's own collection or database.
* `metadata`: fields merged into the attributes of every object from this resource. Declare the ones you filter on in your database's metadata schema.
* `additional_metadata`: free-form fields merged into the custom attributes of every object from this resource.
* `custom_instructions`: guidance for how this resource's documents are interpreted. See [Custom Ingestion Instructions](/essentials/v2/connector-instructions).
* `acl`: who can read this resource's objects. Omitted means unrestricted. See [Access Control](/essentials/v2/access-control).

See [Metadata on synced objects](#metadata-on-synced-objects) for how these merge with the fields HydraDB writes.

### Linear Workspace Documents

Linear documents (the docs you write inside Linear) do not belong to a single team or project, so they sync as one always-present resource instead of per team or project. Discovery returns it alongside the teams and projects:

```json theme={"dark"}
{
  "id": "linear_workspace",
  "name": "Workspace Documents",
  "resource_type": "linear_workspace"
}
```

Each document is indexed as a `knowledge_base` app source. Its markdown body is searchable. Files uploaded into the document (Linear-hosted `uploads.linear.app` files) are downloaded, parsed and indexed too. Plain links to external URLs are kept as metadata, not fetched.

**From the dashboard:** tick "Workspace Documents" in the resource list, the same way you tick a team or project.

**From the API:** include the `linear_workspace` resource in your configure call. To put the documents in their own collection, set `collection` on it, the same as any other resource:

```json theme={"dark"}
{
  "resource_id": "linear_workspace",
  "resource_type": "linear_workspace",
  "name": "Workspace Documents",
  "collection": "linear-docs"
}
```

If you leave `collection` empty, the documents go to the connector's collection.

***

## Changing a connector after setup

Use the endpoint that matches what you want to change. The update endpoints change only the fields you send.

* **One resource's instructions or access rule:** [Update Connector Resource](/api-reference/v2/endpoint/update-connector-resource), `PATCH /connectors/{id}/resources/{resource_id}`.
* **The connector's instructions, sync interval or credentials:** [Update Connector](/api-reference/v2/endpoint/update-connector), `PATCH /connectors/{id}`.
* **Which resources sync, and their collection or metadata:** call [Configure Connector](/api-reference/v2/endpoint/configure-connector) again. Resources you leave out are not touched. For each resource you list, send `name` and `resource_type` again, because omitted values are cleared. Its sync position, instructions and access rule are kept.
* **Stop syncing a resource:** [Delete Connector Resource](/api-reference/v2/endpoint/delete-connector-resource).
* **Stop syncing for a while:** [Pause Connector](/api-reference/v2/endpoint/pause-connector), then [Resume Connector](/api-reference/v2/endpoint/resume-connector).

<Warning>
  Do not use `POST /connectors/{id}/resources` to edit a resource that already exists. It replaces the whole resource: every field you leave out, including its display name and collection, is cleared, and the resource syncs again from the beginning.
</Warning>

***

## Custom ingestion instructions

Use `custom_instructions` to guide how synced documents are interpreted, for example after a product rename. Set a connector-wide default on create or with [Update Connector](/api-reference/v2/endpoint/update-connector), and override it per resource. All connectors support instructions; changes apply from the next sync.

See [Custom Ingestion Instructions](/essentials/v2/connector-instructions) for how the two levels combine, with examples.

***

## Metadata on synced objects

Every object a connector syncs lands in HydraDB with two metadata layers.

### Attributes (`metadata`)

Attributes are the **schema-declared** layer. Fields are declared once in your database's metadata schema and filtered with top-level `metadata_filters` keys. Use them for stable fields you filter on often, such as `department`, `region`, `status` or `priority`.

HydraDB always writes `connector_id` and `provider` here for every synced object. Add your own fields with `metadata` on each resource in configure. Your fields are merged first, so `connector_id` and `provider` always win on conflict.

### Custom attributes (`additional_metadata`)

Custom attributes are the **free-form** layer and need no schema. HydraDB always writes `connector_id` and `resource_id` here, plus provider-native fields such as a Slack message timestamp, a GitHub issue number or a Linear identifier. [List Connector Providers](/api-reference/v2/endpoint/list-connector-providers) shows them for each provider under `filterable_fields`.

Add your own fields with `additional_metadata` on each resource in configure. Your fields are merged first, so provider-generated fields always win on conflict.

This is the layer to filter on to scope a query to one connector, channel, repository or table:

```json Querying with a custom attribute filter theme={"dark"}
{
  "database": "acme_corp",
  "query": "deployment checklist",
  "metadata_filters": {
    "additional_metadata": {
      "connector_id": "{connector_id}"
    }
  }
}
```

Filter on `resource_id` the same way to scope to one channel, repository or table.

***

## Inspect what a connector stores

Every provider publishes a contract describing what it syncs:

* [List Connector Providers](/api-reference/v2/endpoint/list-connector-providers) without `id` returns every provider you can connect.
* [List Connector Providers](/api-reference/v2/endpoint/list-connector-providers), called with `?id={provider}`, describes one: the record types that become searchable, the fields search reaches, the fields you can filter on (each with the `filter_key` to use in `metadata_filters`), and the JSON Schema for its credentials.

Query these endpoints instead of relying on a fixed field list: they cover the whole catalog and stay current as providers change.

<Note>
  You cannot search one searchable field on its own. All of a document's searchable fields are combined into its indexed text, and search runs over that text as a whole. To narrow results by a field, use one of the provider's `filterable_fields` in `metadata_filters`.
</Note>

***

## Permissions on synced content

For supported providers, HydraDB reads the source app's permissions on every sync and applies them as document access rules. That way a query made on behalf of one user cannot surface a private channel, a restricted Drive file, or a repository they cannot see. Slack, Google Drive, GitHub, Confluence and Jira are among the supported providers.

You can also set your own rule per resource, either at configure time with `acl` or afterwards, on its own:

```bash theme={"dark"}
curl -X PATCH 'https://api.hydradb.com/connectors/{id}/resources/C_LEADERSHIP' \
  -H "Authorization: Bearer $HYDRA_DB_API_KEY" \
  -H "API-Version: 2" \
  -H "Content-Type: application/json" \
  -d '{ "acl": ["user_email:grace@acme.com"] }'
```

The change applies to every already-synced document from that resource on the next query, with no re-sync. [Access Control](/essentials/v2/access-control) covers the full rules, including how provider permissions and your own rules interact.

If HydraDB cannot read a resource's permissions from the provider, [Get Connector Status](/api-reference/v2/endpoint/get-connector-status) reports an `acl_warning` on it until the next successful read. Meanwhile your own rule on the resource still applies; a resource with no rule is readable by everyone.

***

## Multiple connectors per provider

You can create more than one connector for the same provider: two Slack workspaces, two GitHub accounts, or a personal and a work Gmail. Each connector is independent, with its own credentials, resources and a distinct `provider_account_scope` (see above). To split one connector's resources across collections, set `collection` per resource in [configure](#configuring-resources).

***

## Related

* [Connectors API reference](/api-reference/v2/endpoint/connectors-overview): every endpoint, and which one changes what
* [Custom Ingestion Instructions](/essentials/v2/connector-instructions): steering how synced content is interpreted
* [App Sources](/essentials/v2/app-sources): the ingestion model connector objects use
* [Metadata](/essentials/v2/metadata): attributes and custom attributes in depth
* [Multi-Tenant](/essentials/v2/multi-tenant): routing resources to databases and collections
* [Query](/essentials/v2/query): querying connector-synced data
* [Access Control](/essentials/v2/access-control): restricting who can retrieve synced content


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.