---
title: "Attach a data source to a table"
method: POST
path: "/external/v1/table/{table_uuid}/sources"
tags: ["Table"]
---

# Attach a data source to a table

`POST /external/v1/table/{table_uuid}/sources`

## Request

- Base URL: `https://api.databar.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.databar.ai/external/v1/table/{table_uuid}/sources`
- Auth: API key in header `x-apikey`

Attach a CSV, webhook, or CRM/API data source to a table.

* ``crm`` requires ``dataset_id`` and optionally a ``schedule`` for recurring syncs.
* ``webhook`` creates a webhook handler (+ raw JSON column) when ``webhook_id`` is omitted.
* ``csv`` records a CSV source; rows are added via the row endpoints.

## Path parameters

- `table_uuid` string, uuid, required

## Request body

- AttachSourceIn: Attach a new data source to a table. * ``crm`` requires ``dataset_id`` (the catalogue Dataset to pull from) and may pass a ``schedule`` for recurring syncs. * ``webhook`` creates a webhook handler in the ``webhook_mode`` mode when ``webhook_id`` is omitted. * ``csv`` records a CSV source; rows are added via the row endpoints.
  - `source_type` 'csv' | 'webhook' | 'crm', required
  - `dataset_id` integer, nullable: Catalogue Dataset id — required for crm sources.
  - `webhook_id` integer, nullable: Existing WebhookTable id to link (webhook sources only).
  - `webhook_mode` 'raw_json' | 'mapping': How a new webhook stores payloads, fixed at creation time. "raw_json" dumps each payload into a single JSON column and works with no further setup; "mapping" leaves the webhook unmapped so the first payload is kept as a sample — then call the webhook-fields and webhook-mapping endpoints to spread fields across columns.
  - `schedule` object, nullable: Optional recurring-sync config for crm sources. Omit to connect the source with NO scheduler (no recurring pulls); only set it to enable scheduled syncs, e.g. {"cron_string": "0 0 * * *", "rows": 100, "overwrite": false}. WARNING: "overwrite": true clears the entire table before each sync.

## Response `200`

OK

- DataSourceOut: Read shape for a table data source returned by the External API. The field set matches ``tables.services.table_source.serialize_source`` (the shared plain serializer the MCP also returns). The internal app has its own DRF ``TableSourceSerializer`` for the UI and is deliberately NOT coupled to this schema — the UI and API/MCP can diverge if their needs differ.
  - `id` integer, required
  - `source_type` string, required
  - `source_type_display` string, nullable
  - `status` string, required
  - `status_display` string, nullable
  - `dataset_id` integer, nullable
  - `webhook_id` integer, nullable
  - `webhook_identifier` string, nullable
  - `webhook_based_integration` string, nullable
  - `webhook_url` string, nullable
  - `webhook_mode` string, nullable
  - `schedule_task_id` integer, nullable
  - `error_message` string, nullable
  - `name` string, nullable
  - `logo` string, nullable
  - `records_count` integer, nullable
  - `last_synced_at` string, nullable
  - `created_at` string, nullable
  - `updated_at` string, nullable

---

[API](https://skmtc.dev/databar/apis/external-api.md) - [All operations](https://skmtc.dev/databar/apis/external-api/llms.txt) - [OpenAPI document](https://skmtc.dev/databar/apis/external-api/revisions/efe15f8bb9bb?raw)
