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

# Data Sources API — Connect and Manage Data Sources

> Use the Data Sources API to list connected integrations, connect new databases or SaaS tools, and remove sources you no longer need.

The Data Sources API lets you list and manage connected data sources programmatically. Use it to automate workspace provisioning, audit your connected integrations, or connect new databases and SaaS tools as part of your infrastructure-as-code workflow. Connecting and removing sources requires the **admin** scope; listing sources requires only the **read** scope.

***

## GET /v1/data-sources — List Data Sources

Retrieve all data sources connected to your workspace.

### Request example

```bash cURL theme={null}
curl https://api.canoanalytics.io/v1/data-sources \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### Response — 200 OK

```json 200 OK theme={null}
{
  "data": [
    {
      "id": "src_4mPk9rZyWc",
      "name": "Production Postgres",
      "type": "postgres",
      "status": "active",
      "last_synced_at": "2024-06-15T14:00:05Z"
    },
    {
      "id": "src_7bQn1xLdFh",
      "name": "Stripe Revenue",
      "type": "stripe",
      "status": "syncing",
      "last_synced_at": "2024-06-15T13:55:00Z"
    },
    {
      "id": "src_2jRw6vMaEt",
      "name": "Legacy BigQuery Export",
      "type": "bigquery",
      "status": "error",
      "last_synced_at": "2024-06-14T02:00:00Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
```

<ResponseField name="data[].id" type="string">
  Unique identifier for the data source.
</ResponseField>

<ResponseField name="data[].name" type="string">
  Human-readable name given to the data source when it was connected.
</ResponseField>

<ResponseField name="data[].type" type="string">
  The data source type (e.g. `postgres`, `mysql`, `bigquery`, `snowflake`, `stripe`).
</ResponseField>

<ResponseField name="data[].status" type="string">
  Current sync status. One of:

  * `active` — syncing normally
  * `syncing` — a sync is currently in progress
  * `error` — the last sync failed; check your credentials or network configuration
  * `paused` — syncing is manually paused
</ResponseField>

<ResponseField name="data[].last_synced_at" type="string">
  ISO 8601 timestamp of the most recently completed sync. `null` if the source has never synced successfully.
</ResponseField>

***

## POST /v1/data-sources — Connect a Data Source

Connect a new data source to your Cano Analytics workspace. This endpoint requires the **admin** scope.

<Warning>
  Never log, print, or expose the `credentials` object. It contains sensitive secrets such as database passwords and API keys. Treat it with the same care as your API key — store it in a secrets manager and transmit it only over HTTPS.
</Warning>

### Body parameters

<ParamField body="name" type="string" required>
  A descriptive name for this data source (e.g. `"Production Postgres"`, `"Stripe Live"`).
</ParamField>

<ParamField body="type" type="string" required>
  The type of data source to connect. Supported values include:
  `postgres`, `mysql`, `bigquery`, `snowflake`, `redshift`, `stripe`, `salesforce`, `hubspot`, `segment`
</ParamField>

<ParamField body="credentials" type="object" required>
  Connection credentials. The required fields depend on the `type`:

  * **postgres / mysql / redshift**: `host`, `port`, `database`, `username`, `password`
  * **bigquery**: `project_id`, `dataset`, `service_account_key` (JSON object)
  * **snowflake**: `account`, `warehouse`, `database`, `username`, `password`
  * **stripe**: `api_key`
  * **salesforce / hubspot**: `access_token` or OAuth credentials
</ParamField>

<ParamField body="schedule" type="object">
  Optional sync schedule. When omitted, Cano Analytics uses the default cadence for your plan.

  * `frequency` (string) — `hourly`, `daily`, or `weekly`
  * `time` (string) — preferred sync time in `HH:MM` UTC format (applies to `daily` and `weekly`)
</ParamField>

### Request example — connecting a PostgreSQL source

```json POST /v1/data-sources theme={null}
{
  "name": "Production Postgres",
  "type": "postgres",
  "credentials": {
    "host": "db.example.com",
    "port": 5432,
    "database": "app_production",
    "username": "readonly_user",
    "password": "s3cr3t_p@ssword"
  },
  "schedule": {
    "frequency": "hourly"
  }
}
```

### Response — 201 Created

```json 201 Created theme={null}
{
  "id": "src_4mPk9rZyWc",
  "name": "Production Postgres",
  "type": "postgres",
  "status": "testing",
  "created_at": "2024-06-15T15:30:00Z"
}
```

<Note>
  When a new source is created, its status is initially `"testing"` while Cano Analytics verifies the credentials and establishes a connection. The status transitions to `active` once the first sync completes successfully, or `error` if the connection check fails.
</Note>

***

## DELETE /v1/data-sources/{id} — Remove a Data Source

Disconnect and remove a data source from your workspace. This endpoint requires the **admin** scope.

<Note>
  Removing a data source does **not** delete historical data that has already been synced into Cano Analytics. Your previously synced tables, events, and reports derived from this source remain intact and queryable. Only future syncs are stopped.
</Note>

### Path parameters

<ParamField path="id" type="string" required>
  The unique identifier of the data source to remove.
</ParamField>

### Request example

```bash cURL theme={null}
curl -X DELETE https://api.canoanalytics.io/v1/data-sources/src_4mPk9rZyWc \
  -H "Authorization: Bearer YOUR_ADMIN_API_KEY"
```

### Response — 204 No Content

A successful deletion returns HTTP `204` with no response body.
