---
title: "Create a sync"
method: POST
path: "/v1/workspaces/{workspace_id}/bases"
tags: ["Syncs"]
---

# Create a sync

`POST /v1/workspaces/{workspace_id}/bases`

## Request

- Base URL: `https://api.stacksync.com`
- URL: `https://api.stacksync.com/v1/workspaces/{workspace_id}/bases`
- Auth: HTTP bearer

Create a sync between two apps from the tables and columns you pair with mapping ids. Stacksync reads both apps, checks every table and column, creates the tables marked `create_new_table` and stores the sync switched off: switch it on with the switch route. Send `validate_only: true` to run every check and get the sync as it would be stored without creating it.

## Path parameters

- `workspace_id` integer, required

## Request body

- CreateSyncBody: The sync to create: two apps whose tables and columns are paired by the mapping ids you choose
  - `base_name` string, required: The name of the sync. 3 to 63 characters: unaccented letters (A-Z, a-z), numbers, underscores, dashes and spaces only; unique in the workspace
  - `base_region` 'besg' | 'usnv', required: The data region the sync runs in; the connections must be in it
  - `apps` SyncAppInput[], required: Exactly two apps
    - `connection_id` string, uuid, required: The connection of the app; the user of the API key must have created it or it must be shared with the workspace
    - `tables` SyncTableInput[], required: The tables to sync, one per table pair; both apps list the same number of tables and the same `table_mapping_id`s
      - `table_name` string, required: The name of the table in the app (its id is accepted too, BigQuery: `project.dataset.table`). For a table being created: the name of the new table, letters, numbers and underscores, at most 63 characters for database apps
      - `table_mapping_id` string, uuid, required: A UUID you choose, the same for the two tables of a pair and different from every other mapping id
      - `sync_direction` 'bidirectional' | 'incoming' | 'outgoing', required: `bidirectional` (paired with `bidirectional`), `incoming` (only written into, paired with `outgoing`) or `outgoing` (only read from, paired with `incoming`)
      - `table_options` SyncTableOptionsInput, required: The options of a table in the sync
        - `create_new_table` boolean, required: True to have Stacksync create this table in the app from the other app's table; the table must then not exist yet and the app must support it (`can_create_tables` of the app schema). At most one table of a pair is created
        - `primary_key` SyncPrimaryKeyInput: The primary key column of a table being created, instead of the default `stacksync_record_id_` of type uuid (Postgres apps only)
          - `column_name` string, required: The name of the primary key column: letters, numbers and underscores, at most 63 characters, not a synced column's name
          - `data_type` 'uuid' | 'text' | 'varchar': The type of the column
      - `columns` SyncColumnInput[]: The columns to sync. Left out on both tables of a pair: every column of the table is synced (and created, for a new table). When sent on both tables they must hold the same `column_mapping_id`s
        - `column_name` string, required: The name of the column in the app (its read id is accepted too). For a table being created it is the name of the new column
        - `column_mapping_id` string, uuid, required: A UUID you choose, the same for the two columns of a pair and different from every other mapping id
    - `rate_limit` SyncRateLimit: The most requests Stacksync makes to the app in a period
      - `rate` integer, required: The number of requests allowed per period, 1 to 2147483647
      - `frequency` 1 | 60 | 3600 | 86400, required: The period of the rate in seconds: 1 (per second), 60 (per minute), 3600 (per hour) or 86400 (per day)
    - `app_options` SyncAppOptionsInput: The options of an app in the sync
      - `delete_protection` boolean: True to keep deletes from reaching this app (set on every table of the app)
  - `base_resource_id` string: A stable id of your choosing, 1 to 60 letters, digits or underscores, unique in the workspace; derived from the name when left out
  - `base_status` string: Accepted and stored as given; leave it out so Stacksync sets the state of the new sync itself
  - `folder_id` string, uuid: The folder of the workspace, in `base_region`, to file the sync under; the root when left out
  - `validate_only` boolean: Run every check of the create, including reading the apps, and answer the sync as it would be stored (its column names after renames, no `base_id`) without creating it

## Response `200`

The sync created (with `validate_only`, the sync as it would be stored, without `base_id`)

- SyncSchemaResponse: The written sync
  - `data` SyncSchema, required: A sync as a create or an edit answers it (the mapping, not the settings: read the sync for those)
    - `base_id` string, uuid: The sync; absent from a `validate_only` create, which creates none
    - `base_name` string, required: The name of the sync
    - `base_region` 'besg' | 'usnv', required: The data region of the sync
    - `base_resource_id` string: The stable id of the sync
    - `base_status` string: The state of the sync when it was sent
    - `apps` SyncSchemaApp[], required: The two apps
      - `app_id` string, required: The id of the app inside the sync
      - `connection_id` string, uuid, required: The connection of the app
      - `rate_limit` SyncRateLimit: The most requests Stacksync makes to the app in a period
        - `rate` integer, required: The number of requests allowed per period, 1 to 2147483647
        - `frequency` 1 | 60 | 3600 | 86400, required: The period of the rate in seconds: 1 (per second), 60 (per minute), 3600 (per hour) or 86400 (per day)
      - `tables` SyncSchemaTable[], required: The synced tables
        - `table_name` string, required: The name of the table in the app
        - `table_mapping_id` string, required: The id shared by the two tables of a pair
        - `sync_direction` 'bidirectional' | 'incoming' | 'outgoing', required: The direction of the table
        - `columns` SyncSchemaColumn[], required: The synced columns
          - `column_name` string, required: The name of the column in the app, after renames
          - `column_mapping_id` string, required: The id shared by the two columns of a pair

## Other responses

- `400`: The body is not valid JSON; a required field is missing, of the wrong type or not allowed (`Invalid Request Body`, `Invalid Input`): `base_name`, `base_region`, `apps` with `connection_id` and `tables` of `table_name`, `table_mapping_id`, `sync_direction`, `table_options.create_new_table`; the name breaks the name rule; `base_resource_id` breaks its pattern; `folder_id` is not a folder of the workspace in the sync's region; the name or resource id is already taken (`Validation Error`); the apps are not two, the tables or columns do not pair (counts, mapping ids, directions, duplicates); a table or column does not exist in its app, a table to create already exists or its app cannot create tables, a rate limit or primary key is invalid; the app refused the credentials or could not be reached; the sync could not be created (`Error creating base`)
- `403`: Forbidden: invalid API key, API key of another workspace, insufficient scope, workspace unavailable, or a non-GET request without `Content-Type: application/json`

---

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