# Data warehouses

> Send conversation messages stored in your data warehouse to Dimension Labs with the universal API.

Connecting a warehouse works the same way as any other [universal API](/api/tracker) integration. You run a scheduled job on your side that queries the conversation rows that are new since its last run and posts each message to Dimension Labs.

## How it works

1. **Get access.** Give the job its own read-only service user, role or service principal.
2. **Query new rows.** Select the rows whose `updated_at` is at or after a stored cursor, with the warehouse's official Node.js driver or SQL API. A row that is updated later is sent again; that's fine, because duplicates are removed automatically.
3. **Map the columns.** Each guide assumes a table with one row per message, and maps its columns to the tracker fields. Use your internal customer id for `userId`, never an email address or phone number.
4. **Send it.** Post each message with `sendToDimensionLabs` from [dimensionlabs.mjs](/api/tracker#set-up-your-project).
5. **Run it.** Load history once with `node run.mjs` and a start date, then run the job every 15 minutes, as in [Scheduled sync](/api/scheduled-sync). History goes to `/trackhistorical` and needs a [backfill](/dimensions/backfill); new rows go to `/track` and are enriched automatically every day.

To bring Dimensions back into your warehouse, each guide ends with a section that pulls them with the [Export API](/api/export) (with an Export API key from **Settings**) and loads the files into a table.

## Guides

| Warehouse | Driver or API used | Guide |
|---|---|---|
| Snowflake | `snowflake-sdk`, key pair authentication | [Snowflake](/integrations/snowflake) |
| Google BigQuery | `@google-cloud/bigquery`, service account | [Google BigQuery](/integrations/bigquery) |
| Databricks | `@databricks/sql`, OAuth service principal | [Databricks](/integrations/databricks) |
| Amazon Redshift | Redshift Data API, IAM | [Amazon Redshift](/integrations/redshift) |

If you would rather not run a job, export the table to a CSV, TSV or JSONL file and [upload it](/data/upload-a-file). Run it through the [file checker](/data/check-a-file) first.
