> For the complete documentation index, see [llms.txt](https://developer.celigo.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.celigo.com/api/api-reference/syncs.md).

# Syncs

Syncs continuously replicate data from source applications into a data warehouse. A sync belongs to an integration and pairs a source connection with a destination database/schema; its **datasets** choose which tables and columns to replicate and how records are loaded. Use these endpoints to create and configure syncs and their datasets, discover the supported source and destination applications and their tables, review change history and schema-drift events, and track usage.

### Sync and dataset schemas

## The Sync object

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"components":{"schemas":{"Sync":{"type":"object","description":"A sync continuously replicates data from a source application into a data warehouse.\nNew syncs start as disabled drafts; a sync can only be enabled once its source,\ndestination, and datasets are fully configured.","required":["_id","_userId","_integrationId","name","disabled","source","destination","driftPolicy"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the sync."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner the sync belongs to."},"_integrationId":{"type":"string","format":"objectId","description":"Integration the sync lives in. Required when creating; cannot be changed\nafterwards — sending it on an update fails with `400 sync_integration_id_update`."},"name":{"type":"string","maxLength":150,"description":"Display name shown in the UI. Defaults to an empty string when not\nprovided at creation."},"description":{"type":"string","maxLength":5120,"description":"Free-form notes about what the sync replicates and why."},"disabled":{"type":"boolean","default":true,"description":"When true, the sync neither runs on schedule nor accepts on-demand runs. New syncs\nstart disabled. Enabling requires a fully configured sync — source and destination\nconnections plus a destination database and schema — and a `historicDateTime`;\notherwise the update fails with `422 sync_not_enabled`."},"schedule":{"type":"string","description":"Cron expression that controls automatic runs, e.g. `? 0 */6 * * *` for every\nsix hours. Empty or omitted means the sync only runs on demand via\n`POST /v1/syncs/{_syncId}/run`. Evaluated in the sync's `timezone`."},"timezone":{"type":"string","description":"IANA time zone name (e.g. `America/New_York`) the `schedule` is evaluated in."},"historicDateTime":{"type":"string","format":"date-time","description":"Earliest record timestamp to backfill from the source. The first run extracts\nhistory from this point forward; later runs are incremental. Must be set before\nthe sync can be enabled."},"source":{"type":"object","description":"Application the sync extracts records from.","required":["_connectionId"],"properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the source application. The application must be one of the\nsupported sync sources returned by `GET /v1/di/metadata/sources`."}}},"destination":{"type":"object","description":"Data warehouse the sync loads records into. Empty (`{}`) on a draft that has no\ndestination yet. The destination application is the connection's own type\n(`rdbms.type` for warehouse connections), so `database` and `schema` are read in that\napplication's terms — Google BigQuery treats them as the GCP project and the dataset.\nEach source + destination host/database/schema combination must be unique across\nsyncs — reusing one fails with `422 duplicate_destination_host` — and all syncs in an\nintegration must target the same destination application type.","properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the destination warehouse. Its application (`rdbms.type` such as\n`snowflake`, `bigquery` or `mssql`, or a NetSuite Analytics Warehouse JDBC\nconnection) is one of the ids returned by `GET /v1/di/metadata/destinations`."},"database":{"type":"string","description":"Database in the destination warehouse the sync loads into. For Google BigQuery this\nis the GCP project id the tables are created in (`project.dataset.table`)."},"schema":{"type":"string","description":"Schema within `database` where the sync creates and loads tables. For Google\nBigQuery this is the dataset name, with case preserved."},"tablePrefix":{"type":"string","description":"Prefix prepended to the name of every table the sync creates in the\ndestination schema. Omit to use unprefixed table names."}}},"driftPolicy":{"$ref":"#/components/schemas/SyncDriftPolicy"}}},"SyncDriftPolicy":{"type":"object","description":"How the sync reacts when the source schema changes between runs (schema drift).\n`dataset` covers whole tables/objects appearing or disappearing; `element` covers\nindividual columns/fields. Drift the policy automates is logged as `Schema Drift`\nevents, readable via `GET /v1/di/resource/syncs/{_syncId}/events`.","properties":{"dataset":{"type":"object","description":"Drift handling for whole tables/objects in the source.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for tables/objects that appear in the source after the sync was\nconfigured. Choose `ignore` to keep the replicated set fixed and add new\ntables manually."},"removed":{"type":"string","enum":["automate"],"description":"Handling for tables/objects deleted from the source. Only automatic\npropagation is supported."}}},"element":{"$ref":"#/components/schemas/ElementDriftPolicy"}}},"ElementDriftPolicy":{"type":"object","description":"How the sync reacts when columns/fields change in the source schema between runs.\n`objectAdded` and `arrayAdded` refine what \"automate\" means for new nested structures and\nare only valid when `added` is `automate` — otherwise the save fails with\n`422 drift_policy_invalid_setup`.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for columns/fields that appear in the source after the sync\nwas configured. Choose `ignore` to keep destination tables stable and\nopt in to new fields manually."},"objectAdded":{"type":"string","enum":["preserve","flatten"],"description":"Shape given to a newly added **object** field when `added` is `automate`."},"arrayAdded":{"type":"string","enum":["preserve","normalize"],"description":"Shape given to a newly added **array** field when `added` is `automate`."},"removed":{"type":"string","enum":["automate"],"description":"Handling for columns/fields deleted from the source. Only automatic\npropagation is supported."},"reduced":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type shrank (e.g. a shorter\nstring length). Only automatic propagation is supported."},"expanded":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type grew (e.g. a wider numeric\nprecision). Only automatic propagation is supported."}},"if":{"anyOf":[{"required":["objectAdded"]},{"required":["arrayAdded"]}]},"then":{"properties":{"added":{"const":"automate"}},"required":["added"]}}}}}
```

## The Dataset object

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"components":{"schemas":{"Dataset":{"type":"object","description":"One table/object a sync replicates, with its per-column selections and load behavior.\nDatasets are scoped to a single sync and are created and updated in bulk via\n`PUT /v1/syncs/{_syncId}/datasets`.","required":["_id","_userId","_syncId","name","externalId","enable","enableAllDataElements","userActionRequired","exportProperties","driftPolicy"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the dataset."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner the dataset belongs to."},"_syncId":{"type":"string","format":"objectId","readOnly":true,"description":"Sync this dataset belongs to. Assigned from the request path at creation."},"name":{"type":"string","description":"Display name of the dataset, typically the source's human-readable label\n(e.g. a Salesforce object's display name). Empty string when never set."},"externalId":{"type":"string","description":"Identifier of the dataset in the source system — the table/object name for\napplication sources, or the export ID when `isExport` is true. Immutable after\ncreation."},"enable":{"type":"boolean","description":"When true, the sync replicates this dataset on each run. Disabled datasets stay\nconfigured but are skipped."},"enableAllDataElements":{"type":"boolean","readOnly":true,"description":"When true, every column in the source dataset is replicated. Computed by the\nplatform: true while the dataset has no explicit `dataElements` selection,\nfalse once one is saved."},"ingestionMode":{"type":"string","enum":["append","replace","merge"],"description":"How each run's extracted records are written into the destination table.\nRequired once the dataset is enabled (`422\ningestion_mode_required_for_enabled_datasets`). `merge` additionally requires a\nprimary-key column in `dataElements`."},"tableName":{"type":"string","description":"Destination table name override. Must be unique among the sync's datasets\n(`422 table_name_already_exists`); required when `isExport` is true. Omit to\nlet the platform derive the table name from the dataset."},"isExport":{"type":"boolean","description":"When true, the dataset's records come from an existing export resource instead\nof a source table; `externalId` then holds the export ID, and the export must\nuse the sync's source connection. Export datasets require `tableName` and an\nexplicit `dataElements` selection, and do not accept `exportProperties`."},"exportProperties":{"type":"object","description":"Extraction behavior for the dataset. Only configurable on source-table\ndatasets — sending it on an export dataset (`isExport: true`) fails\nvalidation; export-backed datasets return a platform-generated stub\n(`{\"delta\": {}}`, no `type`) because extraction follows the export's own\nconfiguration.","properties":{"type":{"type":"string","enum":["delta","all"],"description":"Extraction strategy for each run. Use `delta` for incremental extraction of\nchanged records and `all` to re-extract every record on every run."},"delta":{"type":"object","description":"Incremental-extraction settings. Only used when `type` is `delta`.","properties":{"dateField":{"type":"string","description":"Source field that carries each record's last-modified timestamp, used as\nthe delta cursor. Required for NetSuite datasets that extract via a\n`netsuite.recordType`; Salesforce datasets derive it automatically."}}},"netsuite":{"type":"object","description":"NetSuite-specific extraction settings. Omit for other sources.","properties":{"recordType":{"type":"string","description":"NetSuite record type backing a saved-search dataset. When set with\n`exportProperties.type: delta`, a `delta.dateField` is required."}}}}},"driftPolicy":{"type":"object","description":"Per-dataset override of the sync's `driftPolicy` for column/field drift. Empty\n(`{element: {}}`) when the dataset follows the sync-level policy.","properties":{"element":{"$ref":"#/components/schemas/ElementDriftPolicy"}}},"dataElements":{"type":"array","description":"Per-column replication selections. Absent while `enableAllDataElements` is true\n(every column replicated).","items":{"$ref":"#/components/schemas/DataElement"}},"userActionRequired":{"type":"boolean","readOnly":true,"description":"When true, the platform detected a schema change that needs a user decision\nbefore the dataset can be modified or replicated again — typically drift the\n`driftPolicy` does not automate. Updates to the dataset are rejected until the\nconflict is resolved (in the UI) in the same save that clears the flag."},"mismatchSyncConnection":{"type":"boolean","readOnly":true,"description":"Only present (as `true`) in list responses, on export-backed datasets whose\nexport no longer uses the sync's source connection. Repoint the export or\nrecreate the dataset to resume replicating it."}}},"ElementDriftPolicy":{"type":"object","description":"How the sync reacts when columns/fields change in the source schema between runs.\n`objectAdded` and `arrayAdded` refine what \"automate\" means for new nested structures and\nare only valid when `added` is `automate` — otherwise the save fails with\n`422 drift_policy_invalid_setup`.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for columns/fields that appear in the source after the sync\nwas configured. Choose `ignore` to keep destination tables stable and\nopt in to new fields manually."},"objectAdded":{"type":"string","enum":["preserve","flatten"],"description":"Shape given to a newly added **object** field when `added` is `automate`."},"arrayAdded":{"type":"string","enum":["preserve","normalize"],"description":"Shape given to a newly added **array** field when `added` is `automate`."},"removed":{"type":"string","enum":["automate"],"description":"Handling for columns/fields deleted from the source. Only automatic\npropagation is supported."},"reduced":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type shrank (e.g. a shorter\nstring length). Only automatic propagation is supported."},"expanded":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type grew (e.g. a wider numeric\nprecision). Only automatic propagation is supported."}},"if":{"anyOf":[{"required":["objectAdded"]},{"required":["arrayAdded"]}]},"then":{"properties":{"added":{"const":"automate"}},"required":["added"]}},"DataElement":{"type":"object","description":"Per-column/field replication settings inside a dataset. Elements with nested\nstructure (objects or arrays) carry a `transformMode` and a `children` array;\nscalar elements carry neither.","properties":{"name":{"type":"string","description":"Column/field name exactly as it appears in the source dataset. Discover the\navailable names via\n`GET /v1/di/metadata/connections/{_connectionId}/datasets/{datasetName}/details`."},"enable":{"type":"boolean","description":"When true, the sync extracts and loads this column. Disabled columns are left\nout of the destination table."},"mask":{"type":"boolean","description":"When true, the value is masked before loading so the raw source value never\nlands in the destination. Cannot be combined with `isPrimaryKey`."},"isPrimaryKey":{"type":"boolean","description":"When true, marks the column as (part of) the record key. Required on at least\none enabled scalar column when the dataset's `ingestionMode` is `merge`, and\nused as the parent key for arrays normalized into child tables under `append`\nand `replace`. The element must also be enabled, and cannot carry `mask` or a\n`transformMode`."},"transformMode":{"type":"string","enum":["preserve","flatten","normalize"],"description":"Only set on elements with `children` — it controls how the nested structure is\nloaded. Setting it on a scalar element fails validation, as does omitting it on\nan element that has children. Children nested under a `preserve` parent cannot\noverride it with another mode."},"children":{"type":"array","description":"Nested elements of an object or array field. Present together with\n`transformMode`; empty for scalar columns.","items":{"$ref":"#/components/schemas/DataElement"}}}}}}}
```

## List syncs

> Returns all syncs in the account, sorted by name. Filter to one integration with\
> the \`\_integrationId\` query parameter (equivalent to\
> \`GET /v1/integrations/{\_integrationId}/syncs\`).

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"Include":{"name":"include","in":"query","required":false,"description":"Comma-separated list of fields to project into each returned record.\nTriggers summary projection: the response contains a minimal identity\nset (`_id`, `name`, plus resource-specific fields) with the requested\nfields added on top. Supports dot notation for nested fields.\nMutually exclusive with `exclude`.","schema":{"type":"string"}},"Exclude":{"name":"exclude","in":"query","required":false,"description":"Comma-separated list of fields to strip from the default response.\nUnlike `include`, does not trigger summary projection — returns the\nfull record with the named fields removed. Protected identity fields\n(e.g. `name`) cannot be stripped. Mutually exclusive with `include`.","schema":{"type":"string"}}},"schemas":{"Sync":{"type":"object","description":"A sync continuously replicates data from a source application into a data warehouse.\nNew syncs start as disabled drafts; a sync can only be enabled once its source,\ndestination, and datasets are fully configured.","required":["_id","_userId","_integrationId","name","disabled","source","destination","driftPolicy"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the sync."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner the sync belongs to."},"_integrationId":{"type":"string","format":"objectId","description":"Integration the sync lives in. Required when creating; cannot be changed\nafterwards — sending it on an update fails with `400 sync_integration_id_update`."},"name":{"type":"string","maxLength":150,"description":"Display name shown in the UI. Defaults to an empty string when not\nprovided at creation."},"description":{"type":"string","maxLength":5120,"description":"Free-form notes about what the sync replicates and why."},"disabled":{"type":"boolean","default":true,"description":"When true, the sync neither runs on schedule nor accepts on-demand runs. New syncs\nstart disabled. Enabling requires a fully configured sync — source and destination\nconnections plus a destination database and schema — and a `historicDateTime`;\notherwise the update fails with `422 sync_not_enabled`."},"schedule":{"type":"string","description":"Cron expression that controls automatic runs, e.g. `? 0 */6 * * *` for every\nsix hours. Empty or omitted means the sync only runs on demand via\n`POST /v1/syncs/{_syncId}/run`. Evaluated in the sync's `timezone`."},"timezone":{"type":"string","description":"IANA time zone name (e.g. `America/New_York`) the `schedule` is evaluated in."},"historicDateTime":{"type":"string","format":"date-time","description":"Earliest record timestamp to backfill from the source. The first run extracts\nhistory from this point forward; later runs are incremental. Must be set before\nthe sync can be enabled."},"source":{"type":"object","description":"Application the sync extracts records from.","required":["_connectionId"],"properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the source application. The application must be one of the\nsupported sync sources returned by `GET /v1/di/metadata/sources`."}}},"destination":{"type":"object","description":"Data warehouse the sync loads records into. Empty (`{}`) on a draft that has no\ndestination yet. The destination application is the connection's own type\n(`rdbms.type` for warehouse connections), so `database` and `schema` are read in that\napplication's terms — Google BigQuery treats them as the GCP project and the dataset.\nEach source + destination host/database/schema combination must be unique across\nsyncs — reusing one fails with `422 duplicate_destination_host` — and all syncs in an\nintegration must target the same destination application type.","properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the destination warehouse. Its application (`rdbms.type` such as\n`snowflake`, `bigquery` or `mssql`, or a NetSuite Analytics Warehouse JDBC\nconnection) is one of the ids returned by `GET /v1/di/metadata/destinations`."},"database":{"type":"string","description":"Database in the destination warehouse the sync loads into. For Google BigQuery this\nis the GCP project id the tables are created in (`project.dataset.table`)."},"schema":{"type":"string","description":"Schema within `database` where the sync creates and loads tables. For Google\nBigQuery this is the dataset name, with case preserved."},"tablePrefix":{"type":"string","description":"Prefix prepended to the name of every table the sync creates in the\ndestination schema. Omit to use unprefixed table names."}}},"driftPolicy":{"$ref":"#/components/schemas/SyncDriftPolicy"}}},"SyncDriftPolicy":{"type":"object","description":"How the sync reacts when the source schema changes between runs (schema drift).\n`dataset` covers whole tables/objects appearing or disappearing; `element` covers\nindividual columns/fields. Drift the policy automates is logged as `Schema Drift`\nevents, readable via `GET /v1/di/resource/syncs/{_syncId}/events`.","properties":{"dataset":{"type":"object","description":"Drift handling for whole tables/objects in the source.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for tables/objects that appear in the source after the sync was\nconfigured. Choose `ignore` to keep the replicated set fixed and add new\ntables manually."},"removed":{"type":"string","enum":["automate"],"description":"Handling for tables/objects deleted from the source. Only automatic\npropagation is supported."}}},"element":{"$ref":"#/components/schemas/ElementDriftPolicy"}}},"ElementDriftPolicy":{"type":"object","description":"How the sync reacts when columns/fields change in the source schema between runs.\n`objectAdded` and `arrayAdded` refine what \"automate\" means for new nested structures and\nare only valid when `added` is `automate` — otherwise the save fails with\n`422 drift_policy_invalid_setup`.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for columns/fields that appear in the source after the sync\nwas configured. Choose `ignore` to keep destination tables stable and\nopt in to new fields manually."},"objectAdded":{"type":"string","enum":["preserve","flatten"],"description":"Shape given to a newly added **object** field when `added` is `automate`."},"arrayAdded":{"type":"string","enum":["preserve","normalize"],"description":"Shape given to a newly added **array** field when `added` is `automate`."},"removed":{"type":"string","enum":["automate"],"description":"Handling for columns/fields deleted from the source. Only automatic\npropagation is supported."},"reduced":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type shrank (e.g. a shorter\nstring length). Only automatic propagation is supported."},"expanded":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type grew (e.g. a wider numeric\nprecision). Only automatic propagation is supported."}},"if":{"anyOf":[{"required":["objectAdded"]},{"required":["arrayAdded"]}]},"then":{"properties":{"added":{"const":"automate"}},"required":["added"]}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/syncs":{"get":{"summary":"List syncs","description":"Returns all syncs in the account, sorted by name. Filter to one integration with\nthe `_integrationId` query parameter (equivalent to\n`GET /v1/integrations/{_integrationId}/syncs`).","operationId":"listSyncs","tags":["Syncs"],"parameters":[{"name":"_integrationId","in":"query","required":false,"description":"Only return syncs that belong to this integration.","schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of syncs to return per page.","schema":{"type":"integer","minimum":1,"maximum":1000,"default":1000}},{"name":"after","in":"query","required":false,"description":"Opaque pagination cursor for the next page. Take it from the `after` value in\nthe `Link` response header's `rel=\"next\"` URL rather than constructing it.","schema":{"type":"string"}},{"$ref":"#/components/parameters/Include"},{"$ref":"#/components/parameters/Exclude"}],"responses":{"200":{"description":"Array of sync objects.","headers":{"Link":{"description":"RFC 5988 pagination links. When more pages remain, includes a\n`<...>; rel=\"next\"` entry with an `after` cursor; absent on the\nfinal page.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Sync"}}}}},"204":{"description":"No syncs exist in the account."},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Create a sync

> Creates a sync inside an integration. Only \`\_integrationId\` and\
> \`source.\_connectionId\` are required — new syncs start as disabled drafts, so the\
> destination, datasets, and schedule can be configured with later requests. Creating\
> a sync also registers its connections for the platform's replication runtime.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Request":{"type":"object","description":"Writable sync fields for `POST /v1/syncs` and `PUT /v1/syncs/{_id}`. Updates are full\nreplacements: omitted optional fields (`schedule`, `timezone`, `destination` details,\n`driftPolicy`) are cleared, not preserved, so send the complete desired configuration\non every PUT.","required":["source"],"properties":{"_integrationId":{"type":"string","format":"objectId","description":"Integration to create the sync in. Required on create; forbidden on update —\nthe integration cannot be changed once assigned (`400 sync_integration_id_update`)."},"name":{"type":"string","maxLength":150,"description":"Display name shown in the UI. Values over 150 characters fail with\n`422 size_limit_exceeded`."},"description":{"type":"string","maxLength":5120,"description":"Free-form notes about what the sync replicates and why."},"disabled":{"type":"boolean","default":true,"description":"When true, the sync neither runs on schedule nor accepts on-demand runs. Set to\nfalse only once source, destination, datasets, and `historicDateTime` are all\nconfigured; enabling an incomplete sync fails with `422 sync_not_enabled`."},"schedule":{"type":"string","description":"Cron expression that controls automatic runs, e.g. `? 0 */6 * * *` for every six\nhours. Send an empty string (or omit) for a sync that only runs on demand.\nEvaluated in `timezone`."},"timezone":{"type":"string","description":"IANA time zone name (e.g. `America/New_York`) the `schedule` is evaluated in."},"historicDateTime":{"type":"string","format":"date-time","description":"Earliest record timestamp to backfill from the source. Must be set before the\nsync can be enabled."},"source":{"type":"object","description":"Application the sync extracts records from.","required":["_connectionId"],"properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the source application. The application must be one of the\nsupported sync sources returned by `GET /v1/di/metadata/sources`. Omitting\nit fails with `422 missing_source_connection`."}}},"destination":{"type":"object","description":"Data warehouse the sync loads records into. Omit while drafting; a complete\ndestination (connection, database, schema) is required before the sync can be\nenabled. The destination application is the connection's own type (`rdbms.type`\nfor warehouse connections), so `database` and `schema` are read in that\napplication's terms — Google BigQuery treats them as the GCP project and the\ndataset. The source + destination host/database/schema combination must be unique\nacross syncs (`422 duplicate_destination_host`), and all syncs in an integration\nmust target the same destination application type.","properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the destination warehouse. Its application (`rdbms.type` such as\n`snowflake`, `bigquery` or `mssql`, or a NetSuite Analytics Warehouse JDBC\nconnection) must be one of the ids returned by `GET /v1/di/metadata/destinations`;\nany other connection fails with `422 invalid_destination_type`."},"database":{"type":"string","description":"Database in the destination warehouse the sync loads into; it must already exist.\nFor Google BigQuery this is the GCP project id the tables are created in\n(`project.dataset.table`)."},"schema":{"type":"string","description":"Schema within `database` where the sync creates and loads tables; created on save\nwhen it does not exist. For Google BigQuery this is the dataset name, with case\npreserved."},"tablePrefix":{"type":"string","description":"Prefix prepended to the name of every table the sync creates in the\ndestination schema. Omit to use unprefixed table names."}}},"driftPolicy":{"$ref":"#/components/schemas/SyncDriftPolicy"}}},"SyncDriftPolicy":{"type":"object","description":"How the sync reacts when the source schema changes between runs (schema drift).\n`dataset` covers whole tables/objects appearing or disappearing; `element` covers\nindividual columns/fields. Drift the policy automates is logged as `Schema Drift`\nevents, readable via `GET /v1/di/resource/syncs/{_syncId}/events`.","properties":{"dataset":{"type":"object","description":"Drift handling for whole tables/objects in the source.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for tables/objects that appear in the source after the sync was\nconfigured. Choose `ignore` to keep the replicated set fixed and add new\ntables manually."},"removed":{"type":"string","enum":["automate"],"description":"Handling for tables/objects deleted from the source. Only automatic\npropagation is supported."}}},"element":{"$ref":"#/components/schemas/ElementDriftPolicy"}}},"ElementDriftPolicy":{"type":"object","description":"How the sync reacts when columns/fields change in the source schema between runs.\n`objectAdded` and `arrayAdded` refine what \"automate\" means for new nested structures and\nare only valid when `added` is `automate` — otherwise the save fails with\n`422 drift_policy_invalid_setup`.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for columns/fields that appear in the source after the sync\nwas configured. Choose `ignore` to keep destination tables stable and\nopt in to new fields manually."},"objectAdded":{"type":"string","enum":["preserve","flatten"],"description":"Shape given to a newly added **object** field when `added` is `automate`."},"arrayAdded":{"type":"string","enum":["preserve","normalize"],"description":"Shape given to a newly added **array** field when `added` is `automate`."},"removed":{"type":"string","enum":["automate"],"description":"Handling for columns/fields deleted from the source. Only automatic\npropagation is supported."},"reduced":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type shrank (e.g. a shorter\nstring length). Only automatic propagation is supported."},"expanded":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type grew (e.g. a wider numeric\nprecision). Only automatic propagation is supported."}},"if":{"anyOf":[{"required":["objectAdded"]},{"required":["arrayAdded"]}]},"then":{"properties":{"added":{"const":"automate"}},"required":["added"]}},"Sync":{"type":"object","description":"A sync continuously replicates data from a source application into a data warehouse.\nNew syncs start as disabled drafts; a sync can only be enabled once its source,\ndestination, and datasets are fully configured.","required":["_id","_userId","_integrationId","name","disabled","source","destination","driftPolicy"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the sync."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner the sync belongs to."},"_integrationId":{"type":"string","format":"objectId","description":"Integration the sync lives in. Required when creating; cannot be changed\nafterwards — sending it on an update fails with `400 sync_integration_id_update`."},"name":{"type":"string","maxLength":150,"description":"Display name shown in the UI. Defaults to an empty string when not\nprovided at creation."},"description":{"type":"string","maxLength":5120,"description":"Free-form notes about what the sync replicates and why."},"disabled":{"type":"boolean","default":true,"description":"When true, the sync neither runs on schedule nor accepts on-demand runs. New syncs\nstart disabled. Enabling requires a fully configured sync — source and destination\nconnections plus a destination database and schema — and a `historicDateTime`;\notherwise the update fails with `422 sync_not_enabled`."},"schedule":{"type":"string","description":"Cron expression that controls automatic runs, e.g. `? 0 */6 * * *` for every\nsix hours. Empty or omitted means the sync only runs on demand via\n`POST /v1/syncs/{_syncId}/run`. Evaluated in the sync's `timezone`."},"timezone":{"type":"string","description":"IANA time zone name (e.g. `America/New_York`) the `schedule` is evaluated in."},"historicDateTime":{"type":"string","format":"date-time","description":"Earliest record timestamp to backfill from the source. The first run extracts\nhistory from this point forward; later runs are incremental. Must be set before\nthe sync can be enabled."},"source":{"type":"object","description":"Application the sync extracts records from.","required":["_connectionId"],"properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the source application. The application must be one of the\nsupported sync sources returned by `GET /v1/di/metadata/sources`."}}},"destination":{"type":"object","description":"Data warehouse the sync loads records into. Empty (`{}`) on a draft that has no\ndestination yet. The destination application is the connection's own type\n(`rdbms.type` for warehouse connections), so `database` and `schema` are read in that\napplication's terms — Google BigQuery treats them as the GCP project and the dataset.\nEach source + destination host/database/schema combination must be unique across\nsyncs — reusing one fails with `422 duplicate_destination_host` — and all syncs in an\nintegration must target the same destination application type.","properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the destination warehouse. Its application (`rdbms.type` such as\n`snowflake`, `bigquery` or `mssql`, or a NetSuite Analytics Warehouse JDBC\nconnection) is one of the ids returned by `GET /v1/di/metadata/destinations`."},"database":{"type":"string","description":"Database in the destination warehouse the sync loads into. For Google BigQuery this\nis the GCP project id the tables are created in (`project.dataset.table`)."},"schema":{"type":"string","description":"Schema within `database` where the sync creates and loads tables. For Google\nBigQuery this is the dataset name, with case preserved."},"tablePrefix":{"type":"string","description":"Prefix prepended to the name of every table the sync creates in the\ndestination schema. Omit to use unprefixed table names."}}},"driftPolicy":{"$ref":"#/components/schemas/SyncDriftPolicy"}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/syncs":{"post":{"summary":"Create a sync","description":"Creates a sync inside an integration. Only `_integrationId` and\n`source._connectionId` are required — new syncs start as disabled drafts, so the\ndestination, datasets, and schedule can be configured with later requests. Creating\na sync also registers its connections for the platform's replication runtime.","operationId":"createSync","tags":["Syncs"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"responses":{"201":{"description":"Created sync.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sync"}}}},"400":{"description":"Bad request. `_integrationId` is missing (`missing_integration_id`), the body\ncontains `_id` or `_userId` (`id_and_userId_in_request`), or a connection\nreference is not a valid id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"description":"Validation failed. `source._connectionId` is missing\n(`missing_source_connection`), the destination duplicates another sync\n(`duplicate_destination_host`), the destination connector rejected the\nsync configuration (`invalid_destination_sync_config`), two enabled\ndatasets resolve to the same destination table\n(`conflicting_table_name`), a field exceeds its size limit\n(`size_limit_exceeded`), or the drift policy is inconsistent\n(`drift_policy_invalid_setup`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get a sync

> Returns a single sync by ID.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Sync":{"type":"object","description":"A sync continuously replicates data from a source application into a data warehouse.\nNew syncs start as disabled drafts; a sync can only be enabled once its source,\ndestination, and datasets are fully configured.","required":["_id","_userId","_integrationId","name","disabled","source","destination","driftPolicy"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the sync."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner the sync belongs to."},"_integrationId":{"type":"string","format":"objectId","description":"Integration the sync lives in. Required when creating; cannot be changed\nafterwards — sending it on an update fails with `400 sync_integration_id_update`."},"name":{"type":"string","maxLength":150,"description":"Display name shown in the UI. Defaults to an empty string when not\nprovided at creation."},"description":{"type":"string","maxLength":5120,"description":"Free-form notes about what the sync replicates and why."},"disabled":{"type":"boolean","default":true,"description":"When true, the sync neither runs on schedule nor accepts on-demand runs. New syncs\nstart disabled. Enabling requires a fully configured sync — source and destination\nconnections plus a destination database and schema — and a `historicDateTime`;\notherwise the update fails with `422 sync_not_enabled`."},"schedule":{"type":"string","description":"Cron expression that controls automatic runs, e.g. `? 0 */6 * * *` for every\nsix hours. Empty or omitted means the sync only runs on demand via\n`POST /v1/syncs/{_syncId}/run`. Evaluated in the sync's `timezone`."},"timezone":{"type":"string","description":"IANA time zone name (e.g. `America/New_York`) the `schedule` is evaluated in."},"historicDateTime":{"type":"string","format":"date-time","description":"Earliest record timestamp to backfill from the source. The first run extracts\nhistory from this point forward; later runs are incremental. Must be set before\nthe sync can be enabled."},"source":{"type":"object","description":"Application the sync extracts records from.","required":["_connectionId"],"properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the source application. The application must be one of the\nsupported sync sources returned by `GET /v1/di/metadata/sources`."}}},"destination":{"type":"object","description":"Data warehouse the sync loads records into. Empty (`{}`) on a draft that has no\ndestination yet. The destination application is the connection's own type\n(`rdbms.type` for warehouse connections), so `database` and `schema` are read in that\napplication's terms — Google BigQuery treats them as the GCP project and the dataset.\nEach source + destination host/database/schema combination must be unique across\nsyncs — reusing one fails with `422 duplicate_destination_host` — and all syncs in an\nintegration must target the same destination application type.","properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the destination warehouse. Its application (`rdbms.type` such as\n`snowflake`, `bigquery` or `mssql`, or a NetSuite Analytics Warehouse JDBC\nconnection) is one of the ids returned by `GET /v1/di/metadata/destinations`."},"database":{"type":"string","description":"Database in the destination warehouse the sync loads into. For Google BigQuery this\nis the GCP project id the tables are created in (`project.dataset.table`)."},"schema":{"type":"string","description":"Schema within `database` where the sync creates and loads tables. For Google\nBigQuery this is the dataset name, with case preserved."},"tablePrefix":{"type":"string","description":"Prefix prepended to the name of every table the sync creates in the\ndestination schema. Omit to use unprefixed table names."}}},"driftPolicy":{"$ref":"#/components/schemas/SyncDriftPolicy"}}},"SyncDriftPolicy":{"type":"object","description":"How the sync reacts when the source schema changes between runs (schema drift).\n`dataset` covers whole tables/objects appearing or disappearing; `element` covers\nindividual columns/fields. Drift the policy automates is logged as `Schema Drift`\nevents, readable via `GET /v1/di/resource/syncs/{_syncId}/events`.","properties":{"dataset":{"type":"object","description":"Drift handling for whole tables/objects in the source.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for tables/objects that appear in the source after the sync was\nconfigured. Choose `ignore` to keep the replicated set fixed and add new\ntables manually."},"removed":{"type":"string","enum":["automate"],"description":"Handling for tables/objects deleted from the source. Only automatic\npropagation is supported."}}},"element":{"$ref":"#/components/schemas/ElementDriftPolicy"}}},"ElementDriftPolicy":{"type":"object","description":"How the sync reacts when columns/fields change in the source schema between runs.\n`objectAdded` and `arrayAdded` refine what \"automate\" means for new nested structures and\nare only valid when `added` is `automate` — otherwise the save fails with\n`422 drift_policy_invalid_setup`.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for columns/fields that appear in the source after the sync\nwas configured. Choose `ignore` to keep destination tables stable and\nopt in to new fields manually."},"objectAdded":{"type":"string","enum":["preserve","flatten"],"description":"Shape given to a newly added **object** field when `added` is `automate`."},"arrayAdded":{"type":"string","enum":["preserve","normalize"],"description":"Shape given to a newly added **array** field when `added` is `automate`."},"removed":{"type":"string","enum":["automate"],"description":"Handling for columns/fields deleted from the source. Only automatic\npropagation is supported."},"reduced":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type shrank (e.g. a shorter\nstring length). Only automatic propagation is supported."},"expanded":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type grew (e.g. a wider numeric\nprecision). Only automatic propagation is supported."}},"if":{"anyOf":[{"required":["objectAdded"]},{"required":["arrayAdded"]}]},"then":{"properties":{"added":{"const":"automate"}},"required":["added"]}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/syncs/{_id}":{"get":{"summary":"Get a sync","description":"Returns a single sync by ID.","operationId":"getSync","tags":["Syncs"],"parameters":[{"name":"_id","in":"path","required":true,"description":"Sync id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Sync object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sync"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Update a sync

> Replaces a sync's configuration. Send the complete desired state: omitted optional\
> fields (\`schedule\`, \`timezone\`, destination details, \`driftPolicy\`) are cleared, not\
> preserved. \`\_integrationId\` cannot be sent — the integration is fixed at creation.\
> \
> Set \`disabled: false\` to enable the sync once its source, destination, datasets, and\
> \`historicDateTime\` are configured; enabling an incomplete sync fails with\
> \`422 sync\_not\_enabled\`.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Request":{"type":"object","description":"Writable sync fields for `POST /v1/syncs` and `PUT /v1/syncs/{_id}`. Updates are full\nreplacements: omitted optional fields (`schedule`, `timezone`, `destination` details,\n`driftPolicy`) are cleared, not preserved, so send the complete desired configuration\non every PUT.","required":["source"],"properties":{"_integrationId":{"type":"string","format":"objectId","description":"Integration to create the sync in. Required on create; forbidden on update —\nthe integration cannot be changed once assigned (`400 sync_integration_id_update`)."},"name":{"type":"string","maxLength":150,"description":"Display name shown in the UI. Values over 150 characters fail with\n`422 size_limit_exceeded`."},"description":{"type":"string","maxLength":5120,"description":"Free-form notes about what the sync replicates and why."},"disabled":{"type":"boolean","default":true,"description":"When true, the sync neither runs on schedule nor accepts on-demand runs. Set to\nfalse only once source, destination, datasets, and `historicDateTime` are all\nconfigured; enabling an incomplete sync fails with `422 sync_not_enabled`."},"schedule":{"type":"string","description":"Cron expression that controls automatic runs, e.g. `? 0 */6 * * *` for every six\nhours. Send an empty string (or omit) for a sync that only runs on demand.\nEvaluated in `timezone`."},"timezone":{"type":"string","description":"IANA time zone name (e.g. `America/New_York`) the `schedule` is evaluated in."},"historicDateTime":{"type":"string","format":"date-time","description":"Earliest record timestamp to backfill from the source. Must be set before the\nsync can be enabled."},"source":{"type":"object","description":"Application the sync extracts records from.","required":["_connectionId"],"properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the source application. The application must be one of the\nsupported sync sources returned by `GET /v1/di/metadata/sources`. Omitting\nit fails with `422 missing_source_connection`."}}},"destination":{"type":"object","description":"Data warehouse the sync loads records into. Omit while drafting; a complete\ndestination (connection, database, schema) is required before the sync can be\nenabled. The destination application is the connection's own type (`rdbms.type`\nfor warehouse connections), so `database` and `schema` are read in that\napplication's terms — Google BigQuery treats them as the GCP project and the\ndataset. The source + destination host/database/schema combination must be unique\nacross syncs (`422 duplicate_destination_host`), and all syncs in an integration\nmust target the same destination application type.","properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the destination warehouse. Its application (`rdbms.type` such as\n`snowflake`, `bigquery` or `mssql`, or a NetSuite Analytics Warehouse JDBC\nconnection) must be one of the ids returned by `GET /v1/di/metadata/destinations`;\nany other connection fails with `422 invalid_destination_type`."},"database":{"type":"string","description":"Database in the destination warehouse the sync loads into; it must already exist.\nFor Google BigQuery this is the GCP project id the tables are created in\n(`project.dataset.table`)."},"schema":{"type":"string","description":"Schema within `database` where the sync creates and loads tables; created on save\nwhen it does not exist. For Google BigQuery this is the dataset name, with case\npreserved."},"tablePrefix":{"type":"string","description":"Prefix prepended to the name of every table the sync creates in the\ndestination schema. Omit to use unprefixed table names."}}},"driftPolicy":{"$ref":"#/components/schemas/SyncDriftPolicy"}}},"SyncDriftPolicy":{"type":"object","description":"How the sync reacts when the source schema changes between runs (schema drift).\n`dataset` covers whole tables/objects appearing or disappearing; `element` covers\nindividual columns/fields. Drift the policy automates is logged as `Schema Drift`\nevents, readable via `GET /v1/di/resource/syncs/{_syncId}/events`.","properties":{"dataset":{"type":"object","description":"Drift handling for whole tables/objects in the source.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for tables/objects that appear in the source after the sync was\nconfigured. Choose `ignore` to keep the replicated set fixed and add new\ntables manually."},"removed":{"type":"string","enum":["automate"],"description":"Handling for tables/objects deleted from the source. Only automatic\npropagation is supported."}}},"element":{"$ref":"#/components/schemas/ElementDriftPolicy"}}},"ElementDriftPolicy":{"type":"object","description":"How the sync reacts when columns/fields change in the source schema between runs.\n`objectAdded` and `arrayAdded` refine what \"automate\" means for new nested structures and\nare only valid when `added` is `automate` — otherwise the save fails with\n`422 drift_policy_invalid_setup`.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for columns/fields that appear in the source after the sync\nwas configured. Choose `ignore` to keep destination tables stable and\nopt in to new fields manually."},"objectAdded":{"type":"string","enum":["preserve","flatten"],"description":"Shape given to a newly added **object** field when `added` is `automate`."},"arrayAdded":{"type":"string","enum":["preserve","normalize"],"description":"Shape given to a newly added **array** field when `added` is `automate`."},"removed":{"type":"string","enum":["automate"],"description":"Handling for columns/fields deleted from the source. Only automatic\npropagation is supported."},"reduced":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type shrank (e.g. a shorter\nstring length). Only automatic propagation is supported."},"expanded":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type grew (e.g. a wider numeric\nprecision). Only automatic propagation is supported."}},"if":{"anyOf":[{"required":["objectAdded"]},{"required":["arrayAdded"]}]},"then":{"properties":{"added":{"const":"automate"}},"required":["added"]}},"Sync":{"type":"object","description":"A sync continuously replicates data from a source application into a data warehouse.\nNew syncs start as disabled drafts; a sync can only be enabled once its source,\ndestination, and datasets are fully configured.","required":["_id","_userId","_integrationId","name","disabled","source","destination","driftPolicy"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the sync."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner the sync belongs to."},"_integrationId":{"type":"string","format":"objectId","description":"Integration the sync lives in. Required when creating; cannot be changed\nafterwards — sending it on an update fails with `400 sync_integration_id_update`."},"name":{"type":"string","maxLength":150,"description":"Display name shown in the UI. Defaults to an empty string when not\nprovided at creation."},"description":{"type":"string","maxLength":5120,"description":"Free-form notes about what the sync replicates and why."},"disabled":{"type":"boolean","default":true,"description":"When true, the sync neither runs on schedule nor accepts on-demand runs. New syncs\nstart disabled. Enabling requires a fully configured sync — source and destination\nconnections plus a destination database and schema — and a `historicDateTime`;\notherwise the update fails with `422 sync_not_enabled`."},"schedule":{"type":"string","description":"Cron expression that controls automatic runs, e.g. `? 0 */6 * * *` for every\nsix hours. Empty or omitted means the sync only runs on demand via\n`POST /v1/syncs/{_syncId}/run`. Evaluated in the sync's `timezone`."},"timezone":{"type":"string","description":"IANA time zone name (e.g. `America/New_York`) the `schedule` is evaluated in."},"historicDateTime":{"type":"string","format":"date-time","description":"Earliest record timestamp to backfill from the source. The first run extracts\nhistory from this point forward; later runs are incremental. Must be set before\nthe sync can be enabled."},"source":{"type":"object","description":"Application the sync extracts records from.","required":["_connectionId"],"properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the source application. The application must be one of the\nsupported sync sources returned by `GET /v1/di/metadata/sources`."}}},"destination":{"type":"object","description":"Data warehouse the sync loads records into. Empty (`{}`) on a draft that has no\ndestination yet. The destination application is the connection's own type\n(`rdbms.type` for warehouse connections), so `database` and `schema` are read in that\napplication's terms — Google BigQuery treats them as the GCP project and the dataset.\nEach source + destination host/database/schema combination must be unique across\nsyncs — reusing one fails with `422 duplicate_destination_host` — and all syncs in an\nintegration must target the same destination application type.","properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the destination warehouse. Its application (`rdbms.type` such as\n`snowflake`, `bigquery` or `mssql`, or a NetSuite Analytics Warehouse JDBC\nconnection) is one of the ids returned by `GET /v1/di/metadata/destinations`."},"database":{"type":"string","description":"Database in the destination warehouse the sync loads into. For Google BigQuery this\nis the GCP project id the tables are created in (`project.dataset.table`)."},"schema":{"type":"string","description":"Schema within `database` where the sync creates and loads tables. For Google\nBigQuery this is the dataset name, with case preserved."},"tablePrefix":{"type":"string","description":"Prefix prepended to the name of every table the sync creates in the\ndestination schema. Omit to use unprefixed table names."}}},"driftPolicy":{"$ref":"#/components/schemas/SyncDriftPolicy"}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/syncs/{_id}":{"put":{"summary":"Update a sync","description":"Replaces a sync's configuration. Send the complete desired state: omitted optional\nfields (`schedule`, `timezone`, destination details, `driftPolicy`) are cleared, not\npreserved. `_integrationId` cannot be sent — the integration is fixed at creation.\n\nSet `disabled: false` to enable the sync once its source, destination, datasets, and\n`historicDateTime` are configured; enabling an incomplete sync fails with\n`422 sync_not_enabled`.","operationId":"updateSync","tags":["Syncs"],"parameters":[{"name":"_id","in":"path","required":true,"description":"Sync id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"responses":{"200":{"description":"Updated sync.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sync"}}}},"400":{"description":"Bad request. The body contains `_integrationId` (`sync_integration_id_update`)\nor `_id`/`_userId` (`id_and_userId_in_request`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"description":"Validation failed. `source._connectionId` is missing\n(`missing_source_connection`), the sync is not ready to enable\n(`sync_not_enabled`), the destination duplicates another sync\n(`duplicate_destination_host`), the destination connector rejected the\nsync configuration (`invalid_destination_sync_config`), two enabled\ndatasets resolve to the same destination table\n(`conflicting_table_name`), a field exceeds its size limit\n(`size_limit_exceeded`), or the drift policy is inconsistent\n(`drift_policy_invalid_setup`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Delete a sync

> Deletes a sync and tears down its replication resources, including its datasets.\
> The sync must be disabled first — deleting an enabled sync fails with\
> \`400 sync\_delete\_not\_allowed\`. Syncs are not recoverable through the recycle bin.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/syncs/{_id}":{"delete":{"summary":"Delete a sync","description":"Deletes a sync and tears down its replication resources, including its datasets.\nThe sync must be disabled first — deleting an enabled sync fails with\n`400 sync_delete_not_allowed`. Syncs are not recoverable through the recycle bin.","operationId":"deleteSync","tags":["Syncs"],"parameters":[{"name":"_id","in":"path","required":true,"description":"Sync id.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Sync deleted."},"400":{"description":"The sync is still enabled.\nError code: `sync_delete_not_allowed`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List syncs in an integration

> Returns the syncs that belong to one integration, sorted by name. Equivalent to\
> \`GET /v1/syncs?\_integrationId={\_integrationId}\`.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"Include":{"name":"include","in":"query","required":false,"description":"Comma-separated list of fields to project into each returned record.\nTriggers summary projection: the response contains a minimal identity\nset (`_id`, `name`, plus resource-specific fields) with the requested\nfields added on top. Supports dot notation for nested fields.\nMutually exclusive with `exclude`.","schema":{"type":"string"}},"Exclude":{"name":"exclude","in":"query","required":false,"description":"Comma-separated list of fields to strip from the default response.\nUnlike `include`, does not trigger summary projection — returns the\nfull record with the named fields removed. Protected identity fields\n(e.g. `name`) cannot be stripped. Mutually exclusive with `include`.","schema":{"type":"string"}}},"schemas":{"Sync":{"type":"object","description":"A sync continuously replicates data from a source application into a data warehouse.\nNew syncs start as disabled drafts; a sync can only be enabled once its source,\ndestination, and datasets are fully configured.","required":["_id","_userId","_integrationId","name","disabled","source","destination","driftPolicy"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the sync."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner the sync belongs to."},"_integrationId":{"type":"string","format":"objectId","description":"Integration the sync lives in. Required when creating; cannot be changed\nafterwards — sending it on an update fails with `400 sync_integration_id_update`."},"name":{"type":"string","maxLength":150,"description":"Display name shown in the UI. Defaults to an empty string when not\nprovided at creation."},"description":{"type":"string","maxLength":5120,"description":"Free-form notes about what the sync replicates and why."},"disabled":{"type":"boolean","default":true,"description":"When true, the sync neither runs on schedule nor accepts on-demand runs. New syncs\nstart disabled. Enabling requires a fully configured sync — source and destination\nconnections plus a destination database and schema — and a `historicDateTime`;\notherwise the update fails with `422 sync_not_enabled`."},"schedule":{"type":"string","description":"Cron expression that controls automatic runs, e.g. `? 0 */6 * * *` for every\nsix hours. Empty or omitted means the sync only runs on demand via\n`POST /v1/syncs/{_syncId}/run`. Evaluated in the sync's `timezone`."},"timezone":{"type":"string","description":"IANA time zone name (e.g. `America/New_York`) the `schedule` is evaluated in."},"historicDateTime":{"type":"string","format":"date-time","description":"Earliest record timestamp to backfill from the source. The first run extracts\nhistory from this point forward; later runs are incremental. Must be set before\nthe sync can be enabled."},"source":{"type":"object","description":"Application the sync extracts records from.","required":["_connectionId"],"properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the source application. The application must be one of the\nsupported sync sources returned by `GET /v1/di/metadata/sources`."}}},"destination":{"type":"object","description":"Data warehouse the sync loads records into. Empty (`{}`) on a draft that has no\ndestination yet. The destination application is the connection's own type\n(`rdbms.type` for warehouse connections), so `database` and `schema` are read in that\napplication's terms — Google BigQuery treats them as the GCP project and the dataset.\nEach source + destination host/database/schema combination must be unique across\nsyncs — reusing one fails with `422 duplicate_destination_host` — and all syncs in an\nintegration must target the same destination application type.","properties":{"_connectionId":{"type":"string","format":"objectId","description":"Connection to the destination warehouse. Its application (`rdbms.type` such as\n`snowflake`, `bigquery` or `mssql`, or a NetSuite Analytics Warehouse JDBC\nconnection) is one of the ids returned by `GET /v1/di/metadata/destinations`."},"database":{"type":"string","description":"Database in the destination warehouse the sync loads into. For Google BigQuery this\nis the GCP project id the tables are created in (`project.dataset.table`)."},"schema":{"type":"string","description":"Schema within `database` where the sync creates and loads tables. For Google\nBigQuery this is the dataset name, with case preserved."},"tablePrefix":{"type":"string","description":"Prefix prepended to the name of every table the sync creates in the\ndestination schema. Omit to use unprefixed table names."}}},"driftPolicy":{"$ref":"#/components/schemas/SyncDriftPolicy"}}},"SyncDriftPolicy":{"type":"object","description":"How the sync reacts when the source schema changes between runs (schema drift).\n`dataset` covers whole tables/objects appearing or disappearing; `element` covers\nindividual columns/fields. Drift the policy automates is logged as `Schema Drift`\nevents, readable via `GET /v1/di/resource/syncs/{_syncId}/events`.","properties":{"dataset":{"type":"object","description":"Drift handling for whole tables/objects in the source.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for tables/objects that appear in the source after the sync was\nconfigured. Choose `ignore` to keep the replicated set fixed and add new\ntables manually."},"removed":{"type":"string","enum":["automate"],"description":"Handling for tables/objects deleted from the source. Only automatic\npropagation is supported."}}},"element":{"$ref":"#/components/schemas/ElementDriftPolicy"}}},"ElementDriftPolicy":{"type":"object","description":"How the sync reacts when columns/fields change in the source schema between runs.\n`objectAdded` and `arrayAdded` refine what \"automate\" means for new nested structures and\nare only valid when `added` is `automate` — otherwise the save fails with\n`422 drift_policy_invalid_setup`.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for columns/fields that appear in the source after the sync\nwas configured. Choose `ignore` to keep destination tables stable and\nopt in to new fields manually."},"objectAdded":{"type":"string","enum":["preserve","flatten"],"description":"Shape given to a newly added **object** field when `added` is `automate`."},"arrayAdded":{"type":"string","enum":["preserve","normalize"],"description":"Shape given to a newly added **array** field when `added` is `automate`."},"removed":{"type":"string","enum":["automate"],"description":"Handling for columns/fields deleted from the source. Only automatic\npropagation is supported."},"reduced":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type shrank (e.g. a shorter\nstring length). Only automatic propagation is supported."},"expanded":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type grew (e.g. a wider numeric\nprecision). Only automatic propagation is supported."}},"if":{"anyOf":[{"required":["objectAdded"]},{"required":["arrayAdded"]}]},"then":{"properties":{"added":{"const":"automate"}},"required":["added"]}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_integrationId}/syncs":{"get":{"summary":"List syncs in an integration","description":"Returns the syncs that belong to one integration, sorted by name. Equivalent to\n`GET /v1/syncs?_integrationId={_integrationId}`.","operationId":"listSyncsForIntegration","tags":["Syncs"],"parameters":[{"name":"_integrationId","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of syncs to return per page.","schema":{"type":"integer","minimum":1,"maximum":1000,"default":1000}},{"name":"after","in":"query","required":false,"description":"Opaque pagination cursor for the next page. Take it from the `after` value in\nthe `Link` response header's `rel=\"next\"` URL rather than constructing it.","schema":{"type":"string"}},{"$ref":"#/components/parameters/Include"},{"$ref":"#/components/parameters/Exclude"}],"responses":{"200":{"description":"Array of sync objects.","headers":{"Link":{"description":"RFC 5988 pagination links. When more pages remain, includes a\n`<...>; rel=\"next\"` entry with an `after` cursor; absent on the\nfinal page.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Sync"}}}}},"204":{"description":"The integration has no syncs, or the integration does not exist."},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## List datasets for a sync

> Returns the datasets configured on a sync — the tables/objects it replicates —\
> sorted by name. Export-backed datasets whose export no longer uses the sync's\
> source connection carry \`mismatchSyncConnection: true\`.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"Include":{"name":"include","in":"query","required":false,"description":"Comma-separated list of fields to project into each returned record.\nTriggers summary projection: the response contains a minimal identity\nset (`_id`, `name`, plus resource-specific fields) with the requested\nfields added on top. Supports dot notation for nested fields.\nMutually exclusive with `exclude`.","schema":{"type":"string"}},"Exclude":{"name":"exclude","in":"query","required":false,"description":"Comma-separated list of fields to strip from the default response.\nUnlike `include`, does not trigger summary projection — returns the\nfull record with the named fields removed. Protected identity fields\n(e.g. `name`) cannot be stripped. Mutually exclusive with `include`.","schema":{"type":"string"}}},"schemas":{"Dataset":{"type":"object","description":"One table/object a sync replicates, with its per-column selections and load behavior.\nDatasets are scoped to a single sync and are created and updated in bulk via\n`PUT /v1/syncs/{_syncId}/datasets`.","required":["_id","_userId","_syncId","name","externalId","enable","enableAllDataElements","userActionRequired","exportProperties","driftPolicy"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the dataset."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner the dataset belongs to."},"_syncId":{"type":"string","format":"objectId","readOnly":true,"description":"Sync this dataset belongs to. Assigned from the request path at creation."},"name":{"type":"string","description":"Display name of the dataset, typically the source's human-readable label\n(e.g. a Salesforce object's display name). Empty string when never set."},"externalId":{"type":"string","description":"Identifier of the dataset in the source system — the table/object name for\napplication sources, or the export ID when `isExport` is true. Immutable after\ncreation."},"enable":{"type":"boolean","description":"When true, the sync replicates this dataset on each run. Disabled datasets stay\nconfigured but are skipped."},"enableAllDataElements":{"type":"boolean","readOnly":true,"description":"When true, every column in the source dataset is replicated. Computed by the\nplatform: true while the dataset has no explicit `dataElements` selection,\nfalse once one is saved."},"ingestionMode":{"type":"string","enum":["append","replace","merge"],"description":"How each run's extracted records are written into the destination table.\nRequired once the dataset is enabled (`422\ningestion_mode_required_for_enabled_datasets`). `merge` additionally requires a\nprimary-key column in `dataElements`."},"tableName":{"type":"string","description":"Destination table name override. Must be unique among the sync's datasets\n(`422 table_name_already_exists`); required when `isExport` is true. Omit to\nlet the platform derive the table name from the dataset."},"isExport":{"type":"boolean","description":"When true, the dataset's records come from an existing export resource instead\nof a source table; `externalId` then holds the export ID, and the export must\nuse the sync's source connection. Export datasets require `tableName` and an\nexplicit `dataElements` selection, and do not accept `exportProperties`."},"exportProperties":{"type":"object","description":"Extraction behavior for the dataset. Only configurable on source-table\ndatasets — sending it on an export dataset (`isExport: true`) fails\nvalidation; export-backed datasets return a platform-generated stub\n(`{\"delta\": {}}`, no `type`) because extraction follows the export's own\nconfiguration.","properties":{"type":{"type":"string","enum":["delta","all"],"description":"Extraction strategy for each run. Use `delta` for incremental extraction of\nchanged records and `all` to re-extract every record on every run."},"delta":{"type":"object","description":"Incremental-extraction settings. Only used when `type` is `delta`.","properties":{"dateField":{"type":"string","description":"Source field that carries each record's last-modified timestamp, used as\nthe delta cursor. Required for NetSuite datasets that extract via a\n`netsuite.recordType`; Salesforce datasets derive it automatically."}}},"netsuite":{"type":"object","description":"NetSuite-specific extraction settings. Omit for other sources.","properties":{"recordType":{"type":"string","description":"NetSuite record type backing a saved-search dataset. When set with\n`exportProperties.type: delta`, a `delta.dateField` is required."}}}}},"driftPolicy":{"type":"object","description":"Per-dataset override of the sync's `driftPolicy` for column/field drift. Empty\n(`{element: {}}`) when the dataset follows the sync-level policy.","properties":{"element":{"$ref":"#/components/schemas/ElementDriftPolicy"}}},"dataElements":{"type":"array","description":"Per-column replication selections. Absent while `enableAllDataElements` is true\n(every column replicated).","items":{"$ref":"#/components/schemas/DataElement"}},"userActionRequired":{"type":"boolean","readOnly":true,"description":"When true, the platform detected a schema change that needs a user decision\nbefore the dataset can be modified or replicated again — typically drift the\n`driftPolicy` does not automate. Updates to the dataset are rejected until the\nconflict is resolved (in the UI) in the same save that clears the flag."},"mismatchSyncConnection":{"type":"boolean","readOnly":true,"description":"Only present (as `true`) in list responses, on export-backed datasets whose\nexport no longer uses the sync's source connection. Repoint the export or\nrecreate the dataset to resume replicating it."}}},"ElementDriftPolicy":{"type":"object","description":"How the sync reacts when columns/fields change in the source schema between runs.\n`objectAdded` and `arrayAdded` refine what \"automate\" means for new nested structures and\nare only valid when `added` is `automate` — otherwise the save fails with\n`422 drift_policy_invalid_setup`.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for columns/fields that appear in the source after the sync\nwas configured. Choose `ignore` to keep destination tables stable and\nopt in to new fields manually."},"objectAdded":{"type":"string","enum":["preserve","flatten"],"description":"Shape given to a newly added **object** field when `added` is `automate`."},"arrayAdded":{"type":"string","enum":["preserve","normalize"],"description":"Shape given to a newly added **array** field when `added` is `automate`."},"removed":{"type":"string","enum":["automate"],"description":"Handling for columns/fields deleted from the source. Only automatic\npropagation is supported."},"reduced":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type shrank (e.g. a shorter\nstring length). Only automatic propagation is supported."},"expanded":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type grew (e.g. a wider numeric\nprecision). Only automatic propagation is supported."}},"if":{"anyOf":[{"required":["objectAdded"]},{"required":["arrayAdded"]}]},"then":{"properties":{"added":{"const":"automate"}},"required":["added"]}},"DataElement":{"type":"object","description":"Per-column/field replication settings inside a dataset. Elements with nested\nstructure (objects or arrays) carry a `transformMode` and a `children` array;\nscalar elements carry neither.","properties":{"name":{"type":"string","description":"Column/field name exactly as it appears in the source dataset. Discover the\navailable names via\n`GET /v1/di/metadata/connections/{_connectionId}/datasets/{datasetName}/details`."},"enable":{"type":"boolean","description":"When true, the sync extracts and loads this column. Disabled columns are left\nout of the destination table."},"mask":{"type":"boolean","description":"When true, the value is masked before loading so the raw source value never\nlands in the destination. Cannot be combined with `isPrimaryKey`."},"isPrimaryKey":{"type":"boolean","description":"When true, marks the column as (part of) the record key. Required on at least\none enabled scalar column when the dataset's `ingestionMode` is `merge`, and\nused as the parent key for arrays normalized into child tables under `append`\nand `replace`. The element must also be enabled, and cannot carry `mask` or a\n`transformMode`."},"transformMode":{"type":"string","enum":["preserve","flatten","normalize"],"description":"Only set on elements with `children` — it controls how the nested structure is\nloaded. Setting it on a scalar element fails validation, as does omitting it on\nan element that has children. Children nested under a `preserve` parent cannot\noverride it with another mode."},"children":{"type":"array","description":"Nested elements of an object or array field. Present together with\n`transformMode`; empty for scalar columns.","items":{"$ref":"#/components/schemas/DataElement"}}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/syncs/{_syncId}/datasets":{"get":{"summary":"List datasets for a sync","description":"Returns the datasets configured on a sync — the tables/objects it replicates —\nsorted by name. Export-backed datasets whose export no longer uses the sync's\nsource connection carry `mismatchSyncConnection: true`.","operationId":"listDatasetsForSync","tags":["Syncs"],"parameters":[{"name":"_syncId","in":"path","required":true,"description":"Sync id.","schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of datasets to return per page.","schema":{"type":"integer","minimum":1,"maximum":1000,"default":1000}},{"name":"after","in":"query","required":false,"description":"Opaque pagination cursor for the next page. Take it from the `after` value in\nthe `Link` response header's `rel=\"next\"` URL rather than constructing it.","schema":{"type":"string"}},{"$ref":"#/components/parameters/Include"},{"$ref":"#/components/parameters/Exclude"}],"responses":{"200":{"description":"Array of dataset objects.","headers":{"Link":{"description":"RFC 5988 pagination links. When more pages remain, includes a\n`<...>; rel=\"next\"` entry with an `after` cursor; absent on the\nfinal page.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Dataset"}}}}},"204":{"description":"The sync has no datasets, or the sync does not exist."},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Create or update datasets for a sync

> Creates and updates a sync's datasets in one batch. Each array item either creates\
> a dataset (identified by \`externalId\`) or updates one (identified by \`\_id\`); a\
> single request can mix both. Updates fully replace each dataset's writable fields.\
> The response body is empty — read back the saved datasets with\
> \`GET /v1/syncs/{\_syncId}/datasets\`.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"DatasetUpsertItem":{"type":"object","description":"One dataset to create or update in a `PUT /v1/syncs/{_syncId}/datasets` batch.\nSend `externalId` (without `_id`) to create, or `_id` (without `externalId`) to\nupdate — providing both or neither fails with `400 dataset_externalId_id_required`.\nUpdates are full replacements of the writable fields.","properties":{"_id":{"type":"string","format":"objectId","description":"Dataset to update. The dataset must already belong to the sync in the request\npath. Omit when creating."},"externalId":{"type":"string","description":"Identifier of the dataset in the source system — the table/object name from\n`GET /v1/di/metadata/connections/{_connectionId}/datasets`, or an export ID when\n`isExport` is true. Set when creating; immutable afterwards. A dataset with the\nsame `externalId` must not already exist on the sync."},"name":{"type":"string","description":"Display name of the dataset, typically the source's human-readable label."},"enable":{"type":"boolean","description":"When true, the sync replicates this dataset on each run. Required (with an\n`ingestionMode`) to activate the dataset; datasets created with `enable: false`\nstay configured but skipped."},"ingestionMode":{"type":"string","enum":["append","replace","merge"],"description":"How extracted records are written into the destination table. Required when\n`enable` is true. `merge` requires a primary key in `dataElements`."},"tableName":{"type":"string","description":"Destination table name override. Must be unique among the sync's datasets —\nduplicates within the batch or with existing datasets fail with `400\nduplicate_dataset_table_names` / `422 table_name_already_exists`. Required when\n`isExport` is true."},"isExport":{"type":"boolean","description":"When true, the dataset's records come from an existing export resource:\n`externalId` must be the export's ID, the export must use the sync's source\nconnection (`400 connection_mismatch`), and the item must include `tableName`\nand `dataElements` but no `exportProperties`."},"exportProperties":{"type":"object","description":"Extraction behavior for the dataset. Only for source-table datasets — sending it\nwith `isExport: true` fails validation.","properties":{"type":{"type":"string","enum":["delta","all"],"description":"Extraction strategy for each run. Use `delta` for incremental extraction of\nchanged records and `all` to re-extract every record on every run."},"delta":{"type":"object","description":"Incremental-extraction settings. Only used when `type` is `delta`.","properties":{"dateField":{"type":"string","description":"Source field carrying each record's last-modified timestamp, used as the\ndelta cursor. Required for NetSuite datasets extracted via a\n`netsuite.recordType`; Salesforce datasets derive it automatically."}}},"netsuite":{"type":"object","description":"NetSuite-specific extraction settings. Omit for other sources.","properties":{"recordType":{"type":"string","description":"NetSuite record type backing a saved-search dataset. When set with\n`exportProperties.type: delta`, a `delta.dateField` is required."}}}}},"driftPolicy":{"type":"object","description":"Per-dataset override of the sync's `driftPolicy` for column/field drift. Omit\nto follow the sync-level policy.","properties":{"element":{"$ref":"#/components/schemas/ElementDriftPolicy"}}},"dataElements":{"type":"array","description":"Per-column replication selections. Omit to replicate every column\n(`enableAllDataElements` stays true). When provided, the array replaces the\ndataset's previous selection entirely.","items":{"$ref":"#/components/schemas/DataElement"}}}},"ElementDriftPolicy":{"type":"object","description":"How the sync reacts when columns/fields change in the source schema between runs.\n`objectAdded` and `arrayAdded` refine what \"automate\" means for new nested structures and\nare only valid when `added` is `automate` — otherwise the save fails with\n`422 drift_policy_invalid_setup`.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for columns/fields that appear in the source after the sync\nwas configured. Choose `ignore` to keep destination tables stable and\nopt in to new fields manually."},"objectAdded":{"type":"string","enum":["preserve","flatten"],"description":"Shape given to a newly added **object** field when `added` is `automate`."},"arrayAdded":{"type":"string","enum":["preserve","normalize"],"description":"Shape given to a newly added **array** field when `added` is `automate`."},"removed":{"type":"string","enum":["automate"],"description":"Handling for columns/fields deleted from the source. Only automatic\npropagation is supported."},"reduced":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type shrank (e.g. a shorter\nstring length). Only automatic propagation is supported."},"expanded":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type grew (e.g. a wider numeric\nprecision). Only automatic propagation is supported."}},"if":{"anyOf":[{"required":["objectAdded"]},{"required":["arrayAdded"]}]},"then":{"properties":{"added":{"const":"automate"}},"required":["added"]}},"DataElement":{"type":"object","description":"Per-column/field replication settings inside a dataset. Elements with nested\nstructure (objects or arrays) carry a `transformMode` and a `children` array;\nscalar elements carry neither.","properties":{"name":{"type":"string","description":"Column/field name exactly as it appears in the source dataset. Discover the\navailable names via\n`GET /v1/di/metadata/connections/{_connectionId}/datasets/{datasetName}/details`."},"enable":{"type":"boolean","description":"When true, the sync extracts and loads this column. Disabled columns are left\nout of the destination table."},"mask":{"type":"boolean","description":"When true, the value is masked before loading so the raw source value never\nlands in the destination. Cannot be combined with `isPrimaryKey`."},"isPrimaryKey":{"type":"boolean","description":"When true, marks the column as (part of) the record key. Required on at least\none enabled scalar column when the dataset's `ingestionMode` is `merge`, and\nused as the parent key for arrays normalized into child tables under `append`\nand `replace`. The element must also be enabled, and cannot carry `mask` or a\n`transformMode`."},"transformMode":{"type":"string","enum":["preserve","flatten","normalize"],"description":"Only set on elements with `children` — it controls how the nested structure is\nloaded. Setting it on a scalar element fails validation, as does omitting it on\nan element that has children. Children nested under a `preserve` parent cannot\noverride it with another mode."},"children":{"type":"array","description":"Nested elements of an object or array field. Present together with\n`transformMode`; empty for scalar columns.","items":{"$ref":"#/components/schemas/DataElement"}}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/syncs/{_syncId}/datasets":{"put":{"summary":"Create or update datasets for a sync","description":"Creates and updates a sync's datasets in one batch. Each array item either creates\na dataset (identified by `externalId`) or updates one (identified by `_id`); a\nsingle request can mix both. Updates fully replace each dataset's writable fields.\nThe response body is empty — read back the saved datasets with\n`GET /v1/syncs/{_syncId}/datasets`.","operationId":"upsertDatasetsForSync","tags":["Syncs"],"parameters":[{"name":"_syncId","in":"path","required":true,"description":"Sync id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/DatasetUpsertItem"}}}}},"responses":{"201":{"description":"Datasets created/updated. The response has no body."},"400":{"description":"Bad request. The body is not a non-empty array (`INVALID_REQUEST_BODY` /\n`EMPTY_REQUEST_BODY`), an item has both or neither of `_id`/`externalId`\n(`dataset_externalId_id_required`), an `externalId` already exists or an `_id`\ndoes not belong to the sync, `tableName` values collide\n(`duplicate_dataset_table_names`), or an export dataset's export uses a\ndifferent connection than the sync (`connection_mismatch`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"description":"Validation failed. An enabled dataset is missing `ingestionMode`\n(`ingestion_mode_required_for_enabled_datasets`), a `merge` dataset has no\nprimary key, a `tableName` is already taken, two source columns sanitize to\nthe same destination column name (`duplicate_sanitized_column_names` — rename\nor disable the conflicting source columns), or a data-element combination is\ninvalid (e.g. `transformMode` without children, or `isPrimaryKey` with `mask`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get a dataset

> Returns a single dataset of a sync by ID.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Dataset":{"type":"object","description":"One table/object a sync replicates, with its per-column selections and load behavior.\nDatasets are scoped to a single sync and are created and updated in bulk via\n`PUT /v1/syncs/{_syncId}/datasets`.","required":["_id","_userId","_syncId","name","externalId","enable","enableAllDataElements","userActionRequired","exportProperties","driftPolicy"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the dataset."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner the dataset belongs to."},"_syncId":{"type":"string","format":"objectId","readOnly":true,"description":"Sync this dataset belongs to. Assigned from the request path at creation."},"name":{"type":"string","description":"Display name of the dataset, typically the source's human-readable label\n(e.g. a Salesforce object's display name). Empty string when never set."},"externalId":{"type":"string","description":"Identifier of the dataset in the source system — the table/object name for\napplication sources, or the export ID when `isExport` is true. Immutable after\ncreation."},"enable":{"type":"boolean","description":"When true, the sync replicates this dataset on each run. Disabled datasets stay\nconfigured but are skipped."},"enableAllDataElements":{"type":"boolean","readOnly":true,"description":"When true, every column in the source dataset is replicated. Computed by the\nplatform: true while the dataset has no explicit `dataElements` selection,\nfalse once one is saved."},"ingestionMode":{"type":"string","enum":["append","replace","merge"],"description":"How each run's extracted records are written into the destination table.\nRequired once the dataset is enabled (`422\ningestion_mode_required_for_enabled_datasets`). `merge` additionally requires a\nprimary-key column in `dataElements`."},"tableName":{"type":"string","description":"Destination table name override. Must be unique among the sync's datasets\n(`422 table_name_already_exists`); required when `isExport` is true. Omit to\nlet the platform derive the table name from the dataset."},"isExport":{"type":"boolean","description":"When true, the dataset's records come from an existing export resource instead\nof a source table; `externalId` then holds the export ID, and the export must\nuse the sync's source connection. Export datasets require `tableName` and an\nexplicit `dataElements` selection, and do not accept `exportProperties`."},"exportProperties":{"type":"object","description":"Extraction behavior for the dataset. Only configurable on source-table\ndatasets — sending it on an export dataset (`isExport: true`) fails\nvalidation; export-backed datasets return a platform-generated stub\n(`{\"delta\": {}}`, no `type`) because extraction follows the export's own\nconfiguration.","properties":{"type":{"type":"string","enum":["delta","all"],"description":"Extraction strategy for each run. Use `delta` for incremental extraction of\nchanged records and `all` to re-extract every record on every run."},"delta":{"type":"object","description":"Incremental-extraction settings. Only used when `type` is `delta`.","properties":{"dateField":{"type":"string","description":"Source field that carries each record's last-modified timestamp, used as\nthe delta cursor. Required for NetSuite datasets that extract via a\n`netsuite.recordType`; Salesforce datasets derive it automatically."}}},"netsuite":{"type":"object","description":"NetSuite-specific extraction settings. Omit for other sources.","properties":{"recordType":{"type":"string","description":"NetSuite record type backing a saved-search dataset. When set with\n`exportProperties.type: delta`, a `delta.dateField` is required."}}}}},"driftPolicy":{"type":"object","description":"Per-dataset override of the sync's `driftPolicy` for column/field drift. Empty\n(`{element: {}}`) when the dataset follows the sync-level policy.","properties":{"element":{"$ref":"#/components/schemas/ElementDriftPolicy"}}},"dataElements":{"type":"array","description":"Per-column replication selections. Absent while `enableAllDataElements` is true\n(every column replicated).","items":{"$ref":"#/components/schemas/DataElement"}},"userActionRequired":{"type":"boolean","readOnly":true,"description":"When true, the platform detected a schema change that needs a user decision\nbefore the dataset can be modified or replicated again — typically drift the\n`driftPolicy` does not automate. Updates to the dataset are rejected until the\nconflict is resolved (in the UI) in the same save that clears the flag."},"mismatchSyncConnection":{"type":"boolean","readOnly":true,"description":"Only present (as `true`) in list responses, on export-backed datasets whose\nexport no longer uses the sync's source connection. Repoint the export or\nrecreate the dataset to resume replicating it."}}},"ElementDriftPolicy":{"type":"object","description":"How the sync reacts when columns/fields change in the source schema between runs.\n`objectAdded` and `arrayAdded` refine what \"automate\" means for new nested structures and\nare only valid when `added` is `automate` — otherwise the save fails with\n`422 drift_policy_invalid_setup`.","properties":{"added":{"type":"string","enum":["automate","ignore"],"description":"Handling for columns/fields that appear in the source after the sync\nwas configured. Choose `ignore` to keep destination tables stable and\nopt in to new fields manually."},"objectAdded":{"type":"string","enum":["preserve","flatten"],"description":"Shape given to a newly added **object** field when `added` is `automate`."},"arrayAdded":{"type":"string","enum":["preserve","normalize"],"description":"Shape given to a newly added **array** field when `added` is `automate`."},"removed":{"type":"string","enum":["automate"],"description":"Handling for columns/fields deleted from the source. Only automatic\npropagation is supported."},"reduced":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type shrank (e.g. a shorter\nstring length). Only automatic propagation is supported."},"expanded":{"type":"string","enum":["automate"],"description":"Handling for columns whose source data type grew (e.g. a wider numeric\nprecision). Only automatic propagation is supported."}},"if":{"anyOf":[{"required":["objectAdded"]},{"required":["arrayAdded"]}]},"then":{"properties":{"added":{"const":"automate"}},"required":["added"]}},"DataElement":{"type":"object","description":"Per-column/field replication settings inside a dataset. Elements with nested\nstructure (objects or arrays) carry a `transformMode` and a `children` array;\nscalar elements carry neither.","properties":{"name":{"type":"string","description":"Column/field name exactly as it appears in the source dataset. Discover the\navailable names via\n`GET /v1/di/metadata/connections/{_connectionId}/datasets/{datasetName}/details`."},"enable":{"type":"boolean","description":"When true, the sync extracts and loads this column. Disabled columns are left\nout of the destination table."},"mask":{"type":"boolean","description":"When true, the value is masked before loading so the raw source value never\nlands in the destination. Cannot be combined with `isPrimaryKey`."},"isPrimaryKey":{"type":"boolean","description":"When true, marks the column as (part of) the record key. Required on at least\none enabled scalar column when the dataset's `ingestionMode` is `merge`, and\nused as the parent key for arrays normalized into child tables under `append`\nand `replace`. The element must also be enabled, and cannot carry `mask` or a\n`transformMode`."},"transformMode":{"type":"string","enum":["preserve","flatten","normalize"],"description":"Only set on elements with `children` — it controls how the nested structure is\nloaded. Setting it on a scalar element fails validation, as does omitting it on\nan element that has children. Children nested under a `preserve` parent cannot\noverride it with another mode."},"children":{"type":"array","description":"Nested elements of an object or array field. Present together with\n`transformMode`; empty for scalar columns.","items":{"$ref":"#/components/schemas/DataElement"}}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/syncs/{_syncId}/datasets/{_id}":{"get":{"summary":"Get a dataset","description":"Returns a single dataset of a sync by ID.","operationId":"getDataset","tags":["Syncs"],"parameters":[{"name":"_syncId","in":"path","required":true,"description":"Sync id.","schema":{"type":"string","format":"objectId"}},{"name":"_id","in":"path","required":true,"description":"Dataset id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Dataset object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Dataset"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get audit log for a sync

> Returns the change history for a sync. Entries cover the sync itself \*\*and\*\* the related\
> resources it depends on — its datasets (the tables being replicated) and the source and\
> destination connections it uses — so a single response interleaves \`sync\`, \`dataset\`, and\
> \`connection\` events. Read \`resourceType\` on each entry to tell them apart.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/syncs/{_syncId}/audit":{"get":{"summary":"Get audit log for a sync","description":"Returns the change history for a sync. Entries cover the sync itself **and** the related\nresources it depends on — its datasets (the tables being replicated) and the source and\ndestination connections it uses — so a single response interleaves `sync`, `dataset`, and\n`connection` events. Read `resourceType` on each entry to tell them apart.","tags":["Syncs"],"operationId":"getSyncAudit","parameters":[{"name":"_syncId","in":"path","description":"Sync id.","required":true,"schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","description":"Maximum number of audit entries to return per page.","required":false,"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1000}},{"name":"after","in":"query","required":false,"description":"Opaque pagination cursor for the next page. Take it from the `after` value in the `Link`\nresponse header's `rel=\"next\"` URL rather than constructing it.","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Only return entries at or after this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"description":"Only return entries at or before this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"action","in":"query","required":false,"description":"Filter by the change type. Maps to the `event` field on each entry.","schema":{"type":"string","enum":["create","update","delete","view","restore","purge","signin","signout","purgelogs"]}},{"name":"source","in":"query","required":false,"description":"Filter by how the change was initiated.","schema":{"type":"string","enum":["ui","api","system","connector","script","sso"]}},{"name":"_byUserId","in":"query","required":false,"description":"Filter to changes performed by a single user.","schema":{"type":"string","format":"objectId"}},{"name":"resourceType","in":"query","required":false,"description":"Narrow the aggregated results to a single resource kind — e.g. `sync` for only the sync's\nown changes, excluding its datasets and connections.","schema":{"type":"string","enum":["sync","dataset","connection"]}},{"name":"_resourceId","in":"query","required":false,"description":"Filter to a single resource's entries. Must be sent together with `resourceType`;\nsending it alone returns `400 invalid_id`.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Array of audit entries, newest first.","headers":{"Link":{"description":"RFC 5988 pagination link. Includes `<...>; rel=\"next\"` with an\n`after` cursor when more entries exist; absent on the final page.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"array","items":{"type":"object","description":"A single change recorded against the sync or one of its related resources.","properties":{"_id":{"type":"string","format":"objectId","description":"Unique identifier for this audit entry."},"resourceType":{"type":"string","description":"Which resource the entry describes. The endpoint aggregates the sync and the\nresources it references, so a single response mixes all three values.","enum":["sync","dataset","connection"]},"_resourceId":{"type":"string","format":"objectId","description":"ID of the resource this entry belongs to. Matches `resourceType`."},"event":{"type":"string","description":"Type of change that occurred.","enum":["create","update","delete"]},"source":{"type":"string","description":"How the change was initiated.","enum":["ui","system"]},"time":{"type":"string","format":"date-time","description":"When the change occurred."},"byUser":{"type":"object","description":"User the change is attributed to; always present. For `ui` changes this is the\nuser who made it; for `system` changes it is the account owner the automated\nprocess ran as.","properties":{"_id":{"type":"string","format":"objectId","description":"User ID."},"email":{"type":"string","format":"email","description":"User email address."},"name":{"type":"string","description":"User display name."}}},"fieldChanges":{"type":"array","description":"Fields that were modified. Dot-notation paths reach into nested objects.","items":{"type":"object","description":"One modified field, with its values before and after the change.","properties":{"fieldPath":{"type":"string","description":"Dot-notation path of the changed field."},"oldValue":{"description":"The field's value before the change. Absent on `create` events. Type matches the changed field."},"newValue":{"description":"The field's value after the change. Absent on `delete` events. Type matches the changed field."}}}},"deletedInfo":{"type":"object","description":"Metadata about the deleted resource. Present on `delete` events.","properties":{"name":{"type":"string","description":"Name of the resource at the time of deletion."},"_integrationId":{"type":"string","format":"objectId","description":"Integration the deleted resource belonged to."}}}}}}}}},"204":{"description":"No audit entries match the query."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## List events for a sync

> Returns the events recorded for a sync across all of its runs — schema drift the\
> platform detected or applied, and data-catalog activity — newest first. Events are\
> retained per the account's data retention period; a \`time\_lte\` older than the\
> retention window returns an empty list.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"SyncEvent":{"type":"object","description":"One event recorded while a sync runs — schema drift the platform detected or\nhandled, and data-catalog activity. Events are retained per the account's data\nretention period and ordered newest first.","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the event."},"_userId":{"type":"string","format":"objectId","description":"Account owner the event belongs to."},"_syncId":{"type":"string","format":"objectId","description":"Sync the event was recorded for."},"flowExecutionGroupId":{"type":"string","description":"Run the event belongs to. Matches the `flowExecutionGroupId` returned by\n`POST /v1/syncs/{_syncId}/run` and carried on the run's sync jobs, so events\ncan be correlated with jobs and errors from the same execution."},"resourceName":{"type":"string","description":"Source table/object the event is about."},"severity":{"type":"string","enum":["INFO","WARN","ERROR"],"description":"How much attention the event needs. Informational drift the policy handled\nautomatically is `INFO`; conditions requiring user action surface as `WARN`\nor `ERROR`."},"eventTime":{"type":"string","format":"date-time","description":"Timestamp when the event was recorded."},"type":{"type":"string","enum":["Schema Drift","Data Catalog"],"description":"Event category. Filter the list to one category with the `type` query\nparameter."},"stage":{"type":"string","enum":["Extract","Transform","Load",""],"description":"Pipeline stage the event was recorded in. Empty when the event is not tied to\na specific stage."},"metadata":{"description":"Event-specific detail. For `Schema Drift` events this is an object with an\n`action` (e.g. `Table added`, `Table removed`, `Column added`, `Column removed`,\n`Column expanded`, `Column reduced`, `Column constraint updated`), the\n`resourceType` affected, and — for column-level drift — fields like `fieldName`,\n`oldValue`, `newValue`, or the applied DDL under `query`.","oneOf":[{"title":"object","type":"object","additionalProperties":true},{"title":"string","type":"string"}]}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/di/resource/syncs/{_syncId}/events":{"get":{"summary":"List events for a sync","description":"Returns the events recorded for a sync across all of its runs — schema drift the\nplatform detected or applied, and data-catalog activity — newest first. Events are\nretained per the account's data retention period; a `time_lte` older than the\nretention window returns an empty list.","operationId":"listSyncEvents","tags":["Syncs"],"parameters":[{"name":"_syncId","in":"path","required":true,"description":"Sync id.","schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of events to return per page.","schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}},{"name":"page","in":"query","required":false,"description":"1-based page number. Combine with `limit` to page through results.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"time_lte","in":"query","required":false,"description":"Only return events recorded at or before this timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"time_gt","in":"query","required":false,"description":"Only return events recorded after this timestamp. Must not be in the future\n(`422 future_time_gt_not_allowed`).","schema":{"type":"string","format":"date-time"}},{"name":"type","in":"query","required":false,"description":"Only return events of one category.","schema":{"type":"string","enum":["Schema Drift","Data Catalog"]}},{"name":"resourceName","in":"query","required":false,"description":"Only return events for one source table/object.","schema":{"type":"string"}},{"name":"flowExecutionGroupId","in":"query","required":false,"description":"Only return events from one run. Use the `flowExecutionGroupId` returned by\n`POST /v1/syncs/{_syncId}/run`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Events matching the filters, newest first.","headers":{"Link":{"description":"RFC 5988 pagination links with page-based navigation: `rel=\"first\"`,\n`rel=\"last\"`, and — where applicable — `rel=\"prev\"` and `rel=\"next\"`.","schema":{"type":"string"}},"X-Total-Count":{"description":"Total number of events matching the current filters.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["events"],"properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/SyncEvent"}}}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"description":"The sync belongs to a different account owner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Sync not found.\nError code: `invalid_ref`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid filter. A timestamp value cannot be parsed, or `time_gt` is in the\nfuture (`future_time_gt_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get per-sync usage for the current month

> Returns the number of records each sync loaded during the current calendar month\
> (UTC), for the current environment. Only syncs that ran this month appear.\
> Requires account-administration permission (the same level that manages account\
> users); accounts without a Data Ingestion entitlement get an empty \`usage\` array.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/syncs/usage":{"get":{"summary":"Get per-sync usage for the current month","description":"Returns the number of records each sync loaded during the current calendar month\n(UTC), for the current environment. Only syncs that ran this month appear.\nRequires account-administration permission (the same level that manages account\nusers); accounts without a Data Ingestion entitlement get an empty `usage` array.","operationId":"getSyncUsage","tags":["Syncs"],"responses":{"200":{"description":"Per-sync loaded-record volumes for the current month.","content":{"application/json":{"schema":{"type":"object","required":["usage"],"properties":{"usage":{"type":"array","items":{"type":"object","description":"One sync's loaded-record volume this month.","properties":{"_id":{"type":"string","format":"objectId","description":"Sync the volume belongs to."},"name":{"type":["string","null"],"description":"Sync display name. Null when the sync has since been deleted."},"source":{"type":["object","null"],"description":"The sync's source connection. Null when the sync no longer\nresolves to a source.","properties":{"_id":{"type":"string","format":"objectId","description":"Source connection id."},"name":{"type":["string","null"],"description":"Source connection display name."}}},"destination":{"type":["object","null"],"description":"The sync's destination connection. Null when the sync has no\ndestination configured.","properties":{"_id":{"type":"string","format":"objectId","description":"Destination connection id."},"name":{"type":["string","null"],"description":"Destination connection display name."}}},"volume":{"type":"number","description":"Records the sync loaded this month."}}}}}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## Get monthly sync usage history

> Returns account-wide sync usage by calendar month, newest first — the records\
> loaded across all syncs and environments, alongside the account's Data Ingestion\
> entitlement for each month. History reaches back at most 14 months. Requires\
> account-administration permission (the same level that manages account users);\
> accounts without a Data Ingestion entitlement get an empty array.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/syncs/usage/summary":{"get":{"summary":"Get monthly sync usage history","description":"Returns account-wide sync usage by calendar month, newest first — the records\nloaded across all syncs and environments, alongside the account's Data Ingestion\nentitlement for each month. History reaches back at most 14 months. Requires\naccount-administration permission (the same level that manages account users);\naccounts without a Data Ingestion entitlement get an empty array.","operationId":"getSyncUsageSummary","tags":["Syncs"],"parameters":[{"name":"from","in":"query","required":false,"description":"First month to include, as `YYYY-MM`. Cannot be more than 14 months back\n(`400 invalid_date_range`). Defaults to 14 months before the current month.","schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"}},{"name":"to","in":"query","required":false,"description":"Last month to include, as `YYYY-MM`. Cannot be in the future. Defaults to the\ncurrent month.","schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"}}],"responses":{"200":{"description":"Monthly usage totals, newest month first.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","description":"One month's account-wide sync usage.","required":["year","month","volume","entitlement"],"properties":{"year":{"type":"integer","description":"Calendar year of the usage month."},"month":{"type":"integer","minimum":1,"maximum":12,"description":"Calendar month (1-12) of the usage."},"volume":{"type":"string","description":"Records loaded across all syncs that month, serialized as a string\nto avoid precision loss at high volumes."},"entitlement":{"type":"string","description":"Records per month the account's Data Ingestion license allows,\nserialized as a string."}}}}}}},"400":{"description":"Invalid date range. `from`/`to` is malformed (`invalid_date_format`), or the\nrange is older than 14 months, in the future, or reversed\n(`invalid_date_range`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## Get sync usage by environment

> Returns the records loaded by syncs during the current calendar month (UTC), broken\
> down by environment — production plus every additional environment in the account.\
> Environments with no runs this month report a volume of 0. Requires\
> account-administration permission (the same level that manages account users);\
> accounts without a Data Ingestion entitlement get an empty \`usage\` array.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/syncs/usage/environments":{"get":{"summary":"Get sync usage by environment","description":"Returns the records loaded by syncs during the current calendar month (UTC), broken\ndown by environment — production plus every additional environment in the account.\nEnvironments with no runs this month report a volume of 0. Requires\naccount-administration permission (the same level that manages account users);\naccounts without a Data Ingestion entitlement get an empty `usage` array.","operationId":"getSyncUsageByEnvironment","tags":["Syncs"],"responses":{"200":{"description":"Per-environment loaded-record volumes for the current month.","content":{"application/json":{"schema":{"type":"object","required":["usage"],"properties":{"usage":{"type":"array","items":{"type":"object","description":"One environment's loaded-record volume this month.","required":["environment","volume"],"properties":{"environment":{"type":"object","description":"Environment the volume belongs to.","properties":{"_id":{"type":"string","format":"objectId","description":"Environment id. For the production entry this is the\naccount owner's user id rather than an environment\nresource id."},"name":{"type":"string","description":"Environment display name."}}},"volume":{"type":"number","description":"Records loaded in this environment this month."}}}}}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## List supported sync source applications

> Returns the catalog of applications that can be used as the \*\*source\*\* of a sync — the system\
> a sync extracts records from. Use the returned \`id\` as the source application when building a\
> sync, and \`category\` to group the options in a picker.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/di/metadata/sources":{"get":{"summary":"List supported sync source applications","description":"Returns the catalog of applications that can be used as the **source** of a sync — the system\na sync extracts records from. Use the returned `id` as the source application when building a\nsync, and `category` to group the options in a picker.","tags":["Syncs"],"operationId":"listSyncSources","responses":{"200":{"description":"Array of supported source applications.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","description":"A supported source application.","required":["id"],"properties":{"id":{"type":"string","description":"Application identifier to use as the sync source."},"category":{"type":"string","description":"Display grouping for the application in selection UIs.\nHTTP-connector-backed sources use the category\n`HTTP Connector`."},"displayName":{"type":"string","description":"Human-readable application name. Present on\nHTTP-connector-backed sources."},"source":{"type":"string","description":"Where the source's metadata comes from. Present on\nHTTP-connector-backed sources with the value\n`httpConnectorMetadata`."},"httpConnector":{"type":"object","description":"Identifies the HTTP connector serving this source's\nmetadata. Present only on HTTP-connector-backed sources.","properties":{"_id":{"type":"string","format":"objectId","description":"HTTP connector id."},"_apiId":{"type":["string","null"],"format":"objectId","description":"API group id within the connector. Null for single-API connectors."},"_versionId":{"type":"string","format":"objectId","description":"Connector version id used for metadata resolution."}}}}}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## List supported sync destination applications

> Returns the catalog of applications that can be used as the \*\*destination\*\* of a sync — the\
> data warehouse a sync loads records into. A sync's destination application is the type of\
> its destination connection (\`rdbms.type\` for warehouse connections), which must match one\
> of the returned ids. Identifiers include \`snowflake\` (Snowflake), \`nsaw\` (NetSuite\
> Analytics Warehouse), \`bigquery\` (Google BigQuery), and \`mssql\` (Microsoft SQL Server).

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/di/metadata/destinations":{"get":{"summary":"List supported sync destination applications","description":"Returns the catalog of applications that can be used as the **destination** of a sync — the\ndata warehouse a sync loads records into. A sync's destination application is the type of\nits destination connection (`rdbms.type` for warehouse connections), which must match one\nof the returned ids. Identifiers include `snowflake` (Snowflake), `nsaw` (NetSuite\nAnalytics Warehouse), `bigquery` (Google BigQuery), and `mssql` (Microsoft SQL Server).","tags":["Syncs"],"operationId":"listSyncDestinations","responses":{"200":{"description":"Array of supported destination applications.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","description":"A supported destination application.","required":["id"],"properties":{"id":{"type":"string","description":"Application identifier to use as the sync destination."}}}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## List datasets available on a connection

> Returns the catalog of tables/objects a connection's application exposes for\
> syncing, plus the connection's existing export resources that can back\
> export-based datasets. Use the returned \`name\` values as \`externalId\` when\
> creating datasets via \`PUT /v1/syncs/{\_syncId}/datasets\`.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/di/metadata/connections/{_connectionId}/datasets":{"get":{"summary":"List datasets available on a connection","description":"Returns the catalog of tables/objects a connection's application exposes for\nsyncing, plus the connection's existing export resources that can back\nexport-based datasets. Use the returned `name` values as `externalId` when\ncreating datasets via `PUT /v1/syncs/{_syncId}/datasets`.","operationId":"listConnectionDatasets","tags":["Syncs"],"parameters":[{"name":"_connectionId","in":"path","required":true,"description":"Source connection id.","schema":{"type":"string","format":"objectId"}},{"name":"type","in":"query","required":false,"description":"Restrict the response to one catalog. With `datasets`, only source\ntables/objects are returned; with `exports`, only export resources.","schema":{"type":"string","enum":["datasets","exports","all"],"default":"all"}},{"name":"refreshCache","in":"query","required":false,"description":"When `true`, re-reads the catalog from the source application instead of\nserving the platform's cached copy. Slower; use after making schema changes\nin the source.","schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"Dataset and/or export catalogs, keyed by type.","content":{"application/json":{"schema":{"type":"object","properties":{"datasets":{"type":"array","description":"Tables/objects the source application exposes. Present unless `type` is `exports`.","items":{"type":"object","description":"One syncable table/object in the source application.","required":["name"],"properties":{"name":{"type":"string","description":"Identifier of the table/object in the source system. Use as the\ndataset `externalId`."},"displayName":{"type":"string","description":"Human-readable label for the table/object."}}}},"exports":{"type":"array","description":"Export resources on the connection, usable as export-backed datasets\n(`isExport: true`). Present unless `type` is `datasets`.","items":{"type":"object","description":"One export resource usable as a sync dataset.","properties":{"_id":{"type":"string","format":"objectId","description":"Export id. Use as the dataset `externalId` when creating an\nexport-backed dataset."},"name":{"type":"string","description":"Export display name."},"type":{"type":"string","description":"Export extraction type (e.g. `delta`, `all`, `once`)."},"adaptorType":{"type":"string","description":"Adaptor the export runs on (e.g. `SalesforceExport`)."}}}}}}}}},"400":{"description":"Bad request. The connection id is not a valid id, or `type` is not one of the\nallowed values.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"description":"The catalog could not be fetched from the source application — e.g. the\nconnection is offline or rejects the request.\nError code: `di_fetch_datasets_failure`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get column details for a dataset on a connection

> Returns the full column/field catalog for one table/object on a connection, as read\
> from the source application. Use it to build the \`dataElements\` selection before\
> saving a dataset via \`PUT /v1/syncs/{\_syncId}/datasets\` — each element's \`name\` here\
> is the \`name\` to reference there.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/di/metadata/connections/{_connectionId}/datasets/{datasetName}/details":{"get":{"summary":"Get column details for a dataset on a connection","description":"Returns the full column/field catalog for one table/object on a connection, as read\nfrom the source application. Use it to build the `dataElements` selection before\nsaving a dataset via `PUT /v1/syncs/{_syncId}/datasets` — each element's `name` here\nis the `name` to reference there.","operationId":"getConnectionDatasetDetails","tags":["Syncs"],"parameters":[{"name":"_connectionId","in":"path","required":true,"description":"Source connection id.","schema":{"type":"string","format":"objectId"}},{"name":"datasetName","in":"path","required":true,"description":"Table/object name from `GET /v1/di/metadata/connections/{_connectionId}/datasets`.\nWhen `isExport` is `true`, pass the export id instead.","schema":{"type":"string"}},{"name":"isExport","in":"query","required":false,"description":"Set to `true` when `datasetName` is an export id, to read the export's record\nstructure instead of a source table.","schema":{"type":"string","enum":["true","false"]}},{"name":"refreshCache","in":"query","required":false,"description":"When `true`, re-reads the columns from the source application instead of the\nplatform's cached copy. Use after making schema changes in the source.","schema":{"type":"string","enum":["true","false"]}},{"name":"recordType","in":"query","required":false,"description":"NetSuite record type backing the dataset, for saved-search datasets. Omit for\nother sources.","schema":{"type":"string"}},{"name":"displayName","in":"query","required":false,"description":"NetSuite saved-search display name, sent together with `recordType`.","schema":{"type":"string"}}],"responses":{"200":{"description":"The dataset's column catalog.","content":{"application/json":{"schema":{"type":"object","required":["dataset"],"properties":{"dataset":{"type":"object","description":"Source-side description of one table/object and its columns.","properties":{"name":{"type":"string","description":"Identifier of the table/object in the source system."},"displayName":{"type":"string","description":"Human-readable label for the table/object."},"platform":{"type":"string","description":"Source application the metadata was read from."},"dataSetType":{"type":"string","description":"Source-specific dataset classification (e.g. `Regular`)."},"href":{"type":"string","description":"Source API path the metadata was read from."},"nativeTerminology":{"type":"object","description":"What the source application calls datasets and their columns, for\ndisplay purposes (e.g. Salesforce \"Object\" / \"Fields\").","properties":{"dataset":{"type":"string","description":"Source term for a dataset."},"dataElements":{"type":"string","description":"Source term for a dataset's columns."},"description":{"type":"string","description":"Source field that supplies column descriptions."}}},"deltaFields":{"type":"array","description":"Column names usable as the incremental-extraction cursor\n(`exportProperties.delta.dateField`).","items":{"type":"string"}},"datasetConstraints":{"type":"array","description":"Table-level constraints reported by the source.","items":{"type":"object","properties":{"constraintType":{"type":"string","description":"Constraint kind (e.g. `PRIMARY_KEY`)."},"columns":{"type":"array","description":"Columns the constraint spans.","items":{"type":"string"}}}}},"dataElements":{"type":"array","description":"Every column/field the source exposes on this dataset.","items":{"type":"object","description":"One source column/field.","properties":{"name":{"type":"string","description":"Column/field identifier in the source system."},"displayName":{"type":"string","description":"Human-readable label for the column."},"dataType":{"type":"string","description":"Normalized platform data type."},"nativeDataType":{"type":"string","description":"Data type as reported by the source application."},"dataLength":{"type":"integer","description":"Maximum length for string-like columns; 0 when not applicable."},"precision":{"type":"integer","description":"Numeric precision; 0 when not applicable."},"scale":{"type":"integer","description":"Numeric scale; 0 when not applicable."},"constraint":{"type":"string","description":"Column-level constraint reported by the source (e.g.\n`PRIMARY_KEY`, `FOREIGN_KEY`). Absent for unconstrained\ncolumns."},"isPrimaryKey":{"type":"boolean","description":"Only present (as `true`) on the source's key column(s)."},"description":{"type":["string","null"],"description":"Column help text from the source; null when the source has none."},"fullyQualifiedName":{"type":"string","description":"Globally unique column identifier in the platform's data catalog."},"appSpecificProperties":{"type":"object","description":"Source-specific column attributes (e.g. Salesforce `calculated`).","additionalProperties":true},"children":{"type":["array","null"],"description":"Nested fields for object/array columns; null for scalar columns.","items":{"type":"object","additionalProperties":true}}}}}}}}}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"description":"The columns could not be fetched from the source application — e.g. the\ntable/object does not exist or the connection rejects the request.\nError code: `di_fetch_data_elements_failure`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## List a connection's datasets merged with a sync's configuration

> Returns the connection's full dataset catalog with the sync's saved configuration\
> merged in: catalog entries the sync already replicates carry their stored dataset\
> fields (\`\_id\`, \`enable\`, \`ingestionMode\`, …) plus computed \`totalFieldCount\` and\
> \`selectedFieldCount\`, while unsaved entries appear with catalog fields only.\
> \`dataElements\` arrays are stripped from every item to keep the payload small — read\
> one item's columns with the sync-scoped details endpoint.\
> \
> Use this to render or reconcile a sync's dataset selection; for just the saved\
> datasets, \`GET /v1/syncs/{\_syncId}/datasets\` is lighter.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/di/metadata/sync/{_syncId}/connections/{_connectionId}/datasets":{"get":{"summary":"List a connection's datasets merged with a sync's configuration","description":"Returns the connection's full dataset catalog with the sync's saved configuration\nmerged in: catalog entries the sync already replicates carry their stored dataset\nfields (`_id`, `enable`, `ingestionMode`, …) plus computed `totalFieldCount` and\n`selectedFieldCount`, while unsaved entries appear with catalog fields only.\n`dataElements` arrays are stripped from every item to keep the payload small — read\none item's columns with the sync-scoped details endpoint.\n\nUse this to render or reconcile a sync's dataset selection; for just the saved\ndatasets, `GET /v1/syncs/{_syncId}/datasets` is lighter.","operationId":"listSyncConnectionDatasets","tags":["Syncs"],"parameters":[{"name":"_syncId","in":"path","required":true,"description":"Sync id.","schema":{"type":"string","format":"objectId"}},{"name":"_connectionId","in":"path","required":true,"description":"The sync's source connection id.","schema":{"type":"string","format":"objectId"}},{"name":"type","in":"query","required":false,"description":"Restrict the response to one catalog. With `datasets`, only source\ntables/objects are returned; with `exports`, only export-backed entries.","schema":{"type":"string","enum":["datasets","exports","all"],"default":"all"}},{"name":"refreshCache","in":"query","required":false,"description":"When `true`, re-reads the catalog from the source application instead of the\nplatform's cached copy.","schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"Merged dataset and/or export lists, keyed by type.","content":{"application/json":{"schema":{"type":"object","properties":{"datasets":{"type":"array","description":"Source tables/objects merged with the sync's saved datasets. Present\nunless `type` is `exports`.","items":{"type":"object","description":"One table/object. Catalog-only entries carry `name`/`displayName`\n(and default `exportProperties`); entries the sync has saved also\ncarry the stored dataset fields and field counts.","required":["name"],"properties":{"name":{"type":"string","description":"Display name of the table/object."},"displayName":{"type":"string","description":"Human-readable label for the table/object."},"externalId":{"type":"string","description":"Identifier of the table/object in the source system."},"_id":{"type":"string","format":"objectId","description":"Only present when the sync has saved this dataset. Use with\n`GET /v1/syncs/{_syncId}/datasets/{_id}`."},"enable":{"type":"boolean","description":"When true, the sync replicates this dataset."},"enableAllDataElements":{"type":"boolean","description":"When true, every column is replicated (no explicit selection saved)."},"ingestionMode":{"type":"string","enum":["append","replace","merge"],"description":"How extracted records are written into the destination table."},"exportProperties":{"type":"object","description":"Extraction behavior. Catalog-only entries carry the source's\ndefault (e.g. `{type: delta}`).","properties":{"type":{"type":"string","enum":["delta","all"],"description":"Extraction strategy for each run."}}},"userActionRequired":{"type":"boolean","description":"When true, unhandled schema drift needs a user decision before\nthe dataset can be modified or replicated again."},"totalFieldCount":{"type":"integer","description":"Total number of columns in the dataset, counted recursively\nthrough nested children. 0 for saved datasets that replicate\nall columns without an explicit selection."},"selectedFieldCount":{"type":"integer","description":"Number of enabled columns, counted recursively through nested\nchildren."}}}},"exports":{"type":"array","description":"Export-backed entries merged with the sync's saved export datasets.\nPresent unless `type` is `datasets`.","items":{"type":"object","description":"One export usable as (or already saved as) an export-backed dataset.","properties":{"name":{"type":"string","description":"Export display name."},"externalId":{"type":"string","description":"Export id backing this entry."},"_id":{"type":"string","format":"objectId","description":"Only present when the sync has saved this export as a dataset."},"type":{"type":"string","description":"Export extraction type (e.g. `delta`)."},"adaptorType":{"type":"string","description":"Adaptor the export runs on (e.g. `SalesforceExport`)."},"tableName":{"type":"string","description":"Destination table the export dataset loads into."},"enable":{"type":"boolean","description":"When true, the sync replicates this export dataset."},"ingestionMode":{"type":"string","enum":["append","replace","merge"],"description":"How extracted records are written into the destination table."},"isExport":{"type":"boolean","description":"Always true for entries in this list."},"userActionRequired":{"type":"boolean","description":"When true, unhandled schema drift needs a user decision before\nthe dataset can be modified or replicated again."},"mismatchSyncConnection":{"type":"boolean","description":"Only present (as `true`) when the export no longer uses the\nsync's source connection."},"totalFieldCount":{"type":"integer","description":"Total number of fields in the export's record structure."},"selectedFieldCount":{"type":"integer","description":"Number of enabled fields."}}}}}}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"description":"The sync or connection belongs to a different account owner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The catalog could not be fetched or merged — e.g. the connection is offline or\nthe sync/connection pair does not match.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get column details for a dataset in a sync's context

> Returns one table/object's full column catalog from the source, merged with the\
> sync's saved dataset state — enablement, \`ingestionMode\`, \`exportProperties\`, drift\
> policy, and per-column selections. Use it to edit a dataset's \`dataElements\` with\
> the current source schema and saved selections in one payload.

```json
{"openapi":"3.2.0","info":{"title":"Syncs","version":"1.0.0"},"tags":[{"name":"Syncs","description":"Syncs continuously replicate data from source applications into a data warehouse.\nA sync belongs to an integration and pairs a source connection with a destination\ndatabase/schema; its **datasets** choose which tables and columns to replicate and\nhow records are loaded. Use these endpoints to create and configure syncs and\ntheir datasets, discover the supported source and destination applications and\ntheir tables, review change history and schema-drift events, and track usage.\n\n## Sync and dataset schemas\n\n{% openapi-schemas spec=\"sync\" schemas=\"Sync,Dataset\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/di/metadata/sync/{_syncId}/connections/{_connectionId}/datasets/{datasetName}/details":{"get":{"summary":"Get column details for a dataset in a sync's context","description":"Returns one table/object's full column catalog from the source, merged with the\nsync's saved dataset state — enablement, `ingestionMode`, `exportProperties`, drift\npolicy, and per-column selections. Use it to edit a dataset's `dataElements` with\nthe current source schema and saved selections in one payload.","operationId":"getSyncConnectionDatasetDetails","tags":["Syncs"],"parameters":[{"name":"_syncId","in":"path","required":true,"description":"Sync id.","schema":{"type":"string","format":"objectId"}},{"name":"_connectionId","in":"path","required":true,"description":"The sync's source connection id.","schema":{"type":"string","format":"objectId"}},{"name":"datasetName","in":"path","required":true,"description":"Table/object name from the merged catalog. When `isExport` is `true`, pass the\nsaved dataset's `_id` instead.","schema":{"type":"string"}},{"name":"isExport","in":"query","required":false,"description":"Set to `true` when `datasetName` identifies an export-backed dataset, to read\nthe export's record structure instead of a source table.","schema":{"type":"string","enum":["true","false"]}},{"name":"refreshCache","in":"query","required":false,"description":"When `true`, re-reads the columns from the source application instead of the\nplatform's cached copy.","schema":{"type":"string","enum":["true","false"]}},{"name":"recordType","in":"query","required":false,"description":"NetSuite record type backing the dataset, for saved-search datasets. Omit for\nother sources.","schema":{"type":"string"}},{"name":"displayName","in":"query","required":false,"description":"NetSuite saved-search display name, sent together with `recordType`.","schema":{"type":"string"}}],"responses":{"200":{"description":"The dataset's column catalog merged with the sync's saved state.","content":{"application/json":{"schema":{"type":"object","required":["dataset"],"properties":{"dataset":{"type":"object","description":"The source column catalog (same shape as\n`GET /v1/di/metadata/connections/{_connectionId}/datasets/{datasetName}/details`)\nextended with the sync's saved dataset state when one exists: `_id`,\n`enable`, `isExport`, `ingestionMode`, `exportProperties`,\n`driftPolicy`, `tableName`, and per-element `enable`/`mask`/\n`isPrimaryKey`/`transformMode` selections merged into `dataElements`.","additionalProperties":true}}}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"description":"The sync or connection belongs to a different account owner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The columns could not be fetched or merged — e.g. the table/object does not\nexist in the source or the connection rejects the request.\nError code: `di_fetch_data_elements_failure`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developer.celigo.com/api/api-reference/syncs.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
