# Table Source Resources YAML Reference


> Complete reference for defining your Reverse ETL table source resources using YAML configuration files.



This guide is a detailed reference for the CLI project YAML files that define your Reverse ETL table sources.

**Info:** Table sources require Rudder CLI v0.27.0 or later. The `retl-sources validate` and `retl-sources preview` commands support table sources from v0.28.0. In v0.28.0 and earlier, you must also enable the table source experimental flags. See [Manage Reverse ETL Table Sources using Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/retl-tables/).

## Overview

A table source reads rows straight from a table in your warehouse, or from files under an S3 bucket prefix, with no SQL query in between. To sync the result of a query instead, use a [SQL model](https://www.rudderstack.com/docs/rudder-cli/yaml-sql-models/).

You define a table source by setting `kind` to `retl-source-table`. Table sources use `version: rudder/v1` only. Rudder CLI rejects any other version.

You can store the YAML files anywhere in the project directory. Define one table source per file: `spec` must be a mapping, not a list.

## Table source resources

The `spec` parameter has the following structure:

| Property | Type | Description |
| :----| :-----| :------|
| `id` <br/> Required | String | Unique identifier for the table source within the project. Connections reference the source by this ID. |
| `display_name` <br/> Required | String | Name of the source in the RudderStack dashboard. It must be unique across all your Reverse ETL table and SQL model sources. The comparison ignores case, so `Users` and `users` clash. |
| `source_definition` <br/> Required | String | The warehouse or storage type. One of `postgres`, `redshift`, `snowflake`, `bigquery`, `mysql`, `databricks`, `trino`, or `s3`. <br /><br />This value decides which of the fields below you must set. It can't be changed after the source is created. |
| `account` <br/> Required, unless you set `account_id` | String | Reference to an [account](https://www.rudderstack.com/docs/rudder-cli/yaml-accounts/) defined in the same project, in the form `"#account:<account-id>"`. |
| `account_id` <br/> Required, unless you set `account` | String | The ID of an existing account in your workspace. Get it with `rudder-cli workspace accounts list`. |
| `primary_key` | String | Column that uniquely identifies a row. Required for warehouse sources. Not allowed for `s3`. |
| `schema` | String | Schema, or dataset for BigQuery, that holds the table. Required for warehouse sources. Not allowed for `s3`. |
| `table` | String | Table to read. Required for warehouse sources. Not allowed for `s3`. |
| `bucket_name` | String | S3 bucket to read from. Required for `s3`. Not allowed for warehouse sources. |
| `object_prefix` | String | Key prefix of the files to read, for example `events/2026/`. Required for `s3`. Not allowed for warehouse sources. |
| `enabled` | Boolean | Whether the source is active. <br /><br />**Default value**: `true` |

Set exactly one of `account` and `account_id`.

**Info:** Table sources have no `description` field, because the Reverse ETL API doesn&#39;t store one for table sources.

### Fields by source definition

| Field | Warehouse (`postgres`, `redshift`, `snowflake`, `bigquery`, `mysql`, `databricks`, `trino`) | `s3` |
| :----| :----| :----|
| `id`, `display_name`, `source_definition` | Required | Required |
| `account` or `account_id` | Exactly one | Exactly one |
| `primary_key`, `schema`, `table` | Required | Not allowed |
| `bucket_name`, `object_prefix` | Not allowed | Required |
| `enabled` | Optional | Optional |

### Reference an account

An `account` reference must point to an account in the same project, and that account's type must match `source_definition`. For example, a `postgres` table source can't reference a Snowflake account.

Rudder CLI manages only BigQuery, PostgreSQL, and Snowflake accounts. For other warehouses and for S3, set `account_id` to the ID of an account that already exists in your workspace. Rudder CLI doesn't check a raw `account_id` locally.

## Example definitions

#### Warehouse table

```yaml
version: rudder/v1
kind: retl-source-table
metadata:
  name: users-table
spec:
  id: users-table
  display_name: Users
  account: "#account:prod-pg"
  source_definition: postgres
  primary_key: id
  schema: public
  table: users
  enabled: true
```
#### Existing account ID

```yaml
version: rudder/v1
kind: retl-source-table
metadata:
  name: orders-table
spec:
  id: orders-table
  display_name: Orders
  account_id: "2rzPI1ARibivIvNH5DSpAKGTATy"
  source_definition: redshift
  primary_key: order_id
  schema: analytics
  table: orders
```
#### S3 bucket

```yaml
version: rudder/v1
kind: retl-source-table
metadata:
  name: events-archive
spec:
  id: events-archive
  display_name: Events Archive
  account_id: "2rzPI1ARibivIvNH5DSpAKGTATy"
  source_definition: s3
  bucket_name: my-analytics-bucket
  object_prefix: events/2026/
```

## Validation rules

`rudder-cli validate` and `rudder-cli apply` check table sources before they call the API. Every error names the field it refers to.

| Rule | Error |
| :----| :----|
| `source_definition` is one of the supported values | `'source_definition' must be one of [postgres redshift snowflake bigquery mysql databricks trino s3]` |
| Exactly one of `account` and `account_id` | `'account_id' is required when 'account' is not specified`, or `'account_id' and 'account' cannot be specified together` |
| Warehouse sources set `primary_key`, `schema`, and `table` | `'table' is required unless 'source_definition' is s3` |
| S3 sources don't set `primary_key`, `schema`, or `table` | `'primary_key' is not allowed when 'source_definition' is s3` |
| S3 sources set `bucket_name` and `object_prefix` | `'object_prefix' is required when 'source_definition' is s3` |
| `display_name` is unique across table and SQL model sources, ignoring case | `duplicate display_name 'users' (case-insensitive match with 'Users') across RETL sources` |
| An `account` reference points to an account that matches `source_definition` | `account 'prod-pg' is a 'postgres' account (SOURCE_POSTGRES) and cannot back source_definition 's3'` |

## Update and delete behavior

- **Updates**: Changes to `display_name`, `enabled`, the account, `primary_key`, `bucket_name`, and `object_prefix` update the source in place.
- **`source_definition`**: Changing it fails the apply. Create a new source with a new `id` instead.
- **`schema` and `table`**: Changing either fails the apply while a destination is connected to the source, including connections you created in the dashboard. Delete the connection first, or create a new source for the new table.
- **Delete**: RudderStack refuses to delete a source that still has connections. If the connections are in your project, `rudder-cli apply` deletes them first. Delete connections you created outside the project in the dashboard.

## See also

- [Manage Reverse ETL Table Sources using Rudder CLI](https://www.rudderstack.com/docs/rudder-cli/retl-tables/)
- [Reverse ETL Connections YAML Reference](https://www.rudderstack.com/docs/rudder-cli/yaml-retl-connections/)
- [SQL Model Resources YAML Reference](https://www.rudderstack.com/docs/rudder-cli/yaml-sql-models/)
- [Account Resources YAML Reference](https://www.rudderstack.com/docs/rudder-cli/yaml-accounts/)

