Skip to main content
HydraDB syncs data from 70 apps into your database without ingestion code on your side. You connect an account once, choose which channels, repositories, or pages to sync, and HydraDB keeps their content indexed as searchable app sources. The catalog includes Slack, Gmail, Google Drive, Notion, Jira, Confluence, GitHub, Linear, HubSpot, Zendesk, Supabase, Microsoft Teams, Outlook, Zoom, Gong, and Fireflies. It changes often, so GET /connectors/providers is the current list. If an app is not in the catalog, or you already have your own integration, ingest its data yourself as app sources. This guide builds up in order:
  1. Set up a connector: four calls, shown with a Slack workspace.
  2. Check that it is syncing: status, lifecycle, and syncing on demand.
  3. Change a connector after setup: which call changes what.
  4. Custom ingestion instructions: tell a connector how to read its documents.
  5. Filter on what HydraDB writes: the metadata every synced object carries.
  6. Permissions on synced content: the source app’s permissions, and your own rules.
  7. Connect several accounts of one provider.
  8. Common mistakes and related pages.

1. Set up a connector

Setting up a connector takes four calls, made once. The example connects one Slack workspace; every provider follows the same four calls, and only the credentials and the resource types change. Set up your SDK client before running the Python or TypeScript examples.

Step 1: Pick a provider

GET /connectors/providers returns the catalog; use an entry’s provider value in the next call. With ?id={provider}, it describes one provider, including credential_schema, the credentials it needs.
A catalog entry looks like this:
webhook_support is true for providers whose data arrives by webhook instead of scheduled syncs, such as Supabase.

Step 2: Create the connector

POST /connectors stores the credentials for one provider account and says which database and collection the synced data goes to. Nothing syncs yet.
The response returns the new connector:
Keep connector_id: every later call uses it.

Step 3: Discover what the credentials can reach

GET /connectors/{id}/discover asks Slack which channels the token can see; for GitHub it returns repositories, for Notion pages and databases. Each entry has an id, a name, and a resource_type, which you pass to the next call. Providers that sync a whole account return one entry with id all.
For providers with many resources, page with limit (1 to 100) and cursor, and keep going while has_more is true.

Step 4: Configure the resources to sync

POST /connectors/{id}/configure activates the resources you choose and starts the first sync right away. The example keeps both channels in the connector’s collection and tags each with a department, so one query searches both and a filter can narrow to one.
configured is the number of resources saved. A warnings list names resources that were saved but returned no records when HydraDB tested them; they stay configured and index nothing until they have data.

What each property means

Set the account scope per 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.

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, and you configure it like any other resource. Each document is indexed as a knowledge_base app source: its markdown body is searchable, and 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.
The documents go to the connector’s collection; add collection to route them elsewhere. In the dashboard, tick “Workspace Documents” in the resource list, the same way you tick a team or project.

2. Check that it is syncing

Configure starts the first sync. Data usually appears within a few minutes, and GET /connectors/{id}/status tells you whether the connector and each resource are working in one call.
status is the overall health, such as healthy, degraded, or failed, and lifecycle is what the connector is doing: ingesting until the first sync lands data, then active. Each resource reports its own result, with an action when it failed. Get Connector Status explains every value. From then on, HydraDB syncs every active resource every sync_interval_seconds (one hour by default). Each sync fetches only what changed since the resource’s saved position, its cursor, and ingests it as app sources. Call POST /connectors/{id}/sync when you need data sooner; a 202 means the sync was started, not that it finished. Once lifecycle is active, query the data with POST /query like any other knowledge. Section 5 shows how to scope a query to one connector or one channel.

3. Change a connector after setup

Use the call that matches what you want to change. The update calls change only the fields you send.
  • One resource’s instructions or access rule: Update Connector Resource, PATCH /connectors/{id}/resources/{resource_id}.
  • The connector’s instructions, sync interval, or credentials: Update Connector, PATCH /connectors/{id}. Sending credentials reconnects the connector after a token expired or was revoked; it keeps its id, resources, and sync positions.
  • Which resources sync, and their collection or metadata: call 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.
  • Stop syncing for a while: Pause Connector, then Resume Connector. Each resource resumes from its saved position, so nothing created in the meantime is skipped.
  • Remove the connector: Delete Connector.
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.

4. Custom ingestion instructions

A custom ingestion instruction is free text that a connector reads at sync time and includes when it extracts entities and relationships from every document it syncs. Use one to explain what the documents do not spell out: a product rename, what a channel is for, or what an internal term means. Suppose your product was renamed from Aurora to Nimbus. Years of Slack threads and Confluence pages mention only the old name, none of them states the rename, and a search for “Nimbus” misses all of the earlier context. One instruction on the connector fixes that at ingestion time, with no reconnection.
The instruction applies from the next sync. From then on, documents that mention only Aurora are extracted under the Nimbus entity, with alias links to the old name, so new-name queries reach old-name content through the context graph. The same works for focus (“prioritize decisions, owners, and deadlines; ignore social chatter”), interpretation (“threads in this workspace are incident retros; extract root cause and remediation”), and vocabulary (“SEV1 and SEV2 are incident severities, not product names”). You can also set it when you create the connector, or from the dashboard’s Instructions button. Connector default and resource override: an instruction on the connector applies to every resource without one of its own. An instruction on a resource, such as one Slack channel or one Jira project, replaces the connector default for that resource’s documents rather than adding to it. Set a resource’s instruction with custom_instructions in configure, or afterwards on its own:
An empty string clears an instruction; leaving the field out keeps it, so configuring again never strips a tuned resource. GET /connectors/{id} returns the connector’s instruction, and GET /connectors/{id}/resources returns each resource’s, absent when the resource inherits. In the dashboard, the Instructions dialog lists both levels, each resource marked override or inherits. A few things to know before you write one:
  • Future syncs only: documents already indexed are not processed again; each keeps the instruction it was ingested under. Set instructions before the first sync when you can.
  • Up to 4,000 characters: longer values are rejected with 400, and the stored value stays as it was.
  • Cost: the text goes into the extraction prompt for every synced document, so a long instruction on a busy connector costs on every sync. Say what matters and stop.
  • Be explicit: “X was renamed to Y; they are the same product; index under Y” works far better than vague guidance. Name the exact terms and keep unrelated rules in separate sentences.
  • Interpretation only: instructions do not change which documents sync, where they are stored, or who can read them. Use resource selection, collections, and access rules for those.

5. Filter on what HydraDB writes

Every object a connector syncs lands in HydraDB with two metadata layers, the same two that Metadata describes for everything else. Attributes (metadata) are the schema-declared layer: fields are declared once in your database’s metadata schema and filtered with top-level metadata_filters keys. HydraDB always writes connector_id and provider here for every synced object. Your own metadata from configure is merged first, so connector_id and provider win on conflict. Custom attributes (additional_metadata) 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. Your own additional_metadata from configure is merged first, so provider-generated fields win on conflict. This is the layer to filter on to scope a query to one connector, channel, repository, or table:
Querying with a custom attribute filter
Filter on resource_id the same way to scope to one channel, repository, or table.
To see which provider-native fields a connector writes, call GET /connectors/providers?id={provider}. Its filterable_fields each carry the filter_key to use in metadata_filters. Its searchable_fields are combined into each document’s searchable text, so you search them together, not one at a time.

6. Permissions on synced content

For supported providers, HydraDB reads the source app’s permissions on every sync and applies them as document access rules, so a query made on someone’s behalf 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; Access Control lists what is captured for each. You can also set your own rule per resource, either at configure time with acl or afterwards, on its own:
The change applies to already-synced documents on the next query, with no re-sync. Where HydraDB reads the provider’s permissions, those take over again at the next sync; Access Control explains which wins when they disagree. If HydraDB cannot read a resource’s permissions from the provider, 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.

7. Connect several accounts of one provider

You can create more than one connector for the same provider: two Slack workspaces, two GitHub organizations, or a personal and a work Gmail. Each connector is independent, with its own credentials, resources, and provider_account_scope. Give each a distinct provider_account_scope, or objects from the two accounts that happen to share an external id can overwrite each other in the same database and collection. All of them can sync into the same collection, so one query searches every account. To keep one account’s resources apart, set collection per resource in configure.

Common mistakes

  • Editing an existing resource with POST /connectors/{id}/resources: the resource is replaced and syncs again from the beginning. Use PATCH /connectors/{id}/resources/{resource_id} for instructions and access rules, or configure again for routing and metadata.
  • Reconfiguring without name and resource_type: omitted values are cleared. Send both every time you list a resource.
  • Expecting a resource instruction to add to the connector default: it replaces it. Repeat anything from the default that the resource still needs.
  • Two accounts of one provider with the same provider_account_scope: objects that share an external id overwrite each other. Set a distinct scope per account.
  • Filtering on a provider field as a top-level key: provider-native fields live in additional_metadata. Use the filter_key from the provider description.
  • Querying before the first sync has landed: lifecycle reads ingesting until then. Wait for active, or check GET /connectors/{id}/status.