> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://apidocs.polytomic.com/2023-04-25/quickstart/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://apidocs.polytomic.com/_mcp/server. ## Prerequisites This guide makes use of [cURL](https://curl.se/), a command line program for making HTTP requests. MacOS and many Linux distributions have cURL pre-installed, and it is also available for download on Windows and many other operating systems. ## Setup Generate an API key in the your [user settings panel](https://app.polytomic.com/settings/user) For more information, see the [authentication section](https://docs.polytomic.com/reference/authentication#api-keys). ## Making API Requests Set the API token as an environment variable: ```text export POLYTOMIC_API_KEY=YOUR-API-TOKEN ``` Replace `YOUR-API-TOKEN` with the token you just generate in the step above. Make a request to the identity endpoint: ```bash curl --request GET \ --url https://app.polytomic.com/api/me \ --header "accept: application/json" \ --header "X-Polytomic-Version: 2022-12-12" \ --header "Authorization: Bearer ${POLYTOMIC_API_KEY}" ``` ### 1. Create a Connection The following request will create a MySQL connection. The configuration for each type of connection can be found at the [connection configuration](https://apidocs.polytomic.com/2023-04-25/configuring-your-connections) page in our documentation. ```bash curl --request POST \ --url https://app.polytomic.com/api/connections \ --header "accept: application/json" \ --header "content-type: application/json" \ --header "X-Polytomic-Version: 2022-12-12" \ --header "Authorization: Bearer ${POLYTOMIC_API_KEY}" \ -d '{ "name": "MySQL Connection", "type": "mysql", "configuration": { "hostname": "localhost", "port": 3306, "dbname": "company", "account": "user", "passwd": "secret" } }' ``` #### OAuth Connections OAuth connections require completing the connection authentication process in the browser. An example of creating an OAuth connection can be found in the recipes section of the docs. ### 2. Create a Model Next we'll create a model of a "customers" table using the MySQL connection we just created. Connections can be enumerated using the [source endpoint](https://docs.polytomic.com/reference/quickstart#1-create-a-connection:~:text=enumerated%20using%20the-,source%20endpoint,-.%20This%20next%20call). This next call will show us all available tables on the connection we just created: ```bash curl --request GET \ --url https://app.polytomic.com/api/connections/{YOUR-CONNECTION-ID}/source \ --header "content-type: application/json" \ --header "X-Polytomic-Version: 2022-12-12" \ --header "Authorization: Bearer ${POLYTOMIC_API_KEY}" ``` The response will look like: ```json { "data": { "items": { "project_id": { "items": null, "requires_one_of": null, "has_items": false }, "query": { "items": null, "requires_one_of": null, "has_items": false }, "table": { "items": [ "company.accounts", "company.customers", "company.teams" ], "requires_one_of": null, "has_items": true }, "tracking_columns": { "items": null, "requires_one_of": null, "has_items": false }, "view": { "items": null, "requires_one_of": null, "has_items": false } }, "requires_one_of": [ "query", "table", "view" ] } } ``` #### Sources Each source level can be drilled down by using query parameters. e.g. `?table=company.accounts`. In this case; however, tables requires\_one\_of property is null so we don't need to drill down. Finally, we can create a model using the company.customers table like we mentioned above: ```bash curl --request POST \ --url https://app.polytomic.com/api/models \ --header "accept: application/json" \ --header "content-type: application/json" \ --header "X-Polytomic-Version: 2022-12-12" \ --header "Authorization: Bearer ${POLYTOMIC_API_KEY}" \ -d '{ "name": "Customer Model", "configuration": { "table": "company.customers" }, "connection_id": "YOUR-CONNECTION-ID" }' ``` \ > **Note** > > Important: Make sure to replace `YOUR-CONNECTION-ID` with the returned connection ID. ### 3. Create a sync Next we'll create a sync using the customer model we created above. We'll also create an additional connection that we will use as the target. #### Create a target Here, we'll create a Snowflake connection as our target. ```bash curl --request POST \ --url https://app.polytomic.com/api/connections \ --header "accept: application/json" \ --header "content-type: application/json" \ --header "X-Polytomic-Version: 2022-12-12" \ --header "Authorization: Bearer ${POLYTOMIC_API_KEY}" \ -d '{ "name": "Snowflake Connection", "type": "snowflake", "configuration": { "account": "account", "dbname": "database", "password": "secret-password", "username": "user" } }' ``` #### Enumerate target In the same way sources can be enumerated, so can targets. ```bash curl --request GET \ --url https://app.polytomic.com/api/connections/YOUR-CONNECTION-ID/target \ --header "accept: application/json" \ --header "content-type: application/json" \ --header "X-Polytomic-Version: 2022-12-12" \ --header "Authorization: Bearer ${POLYTOMIC_API_KEY}" ``` The response will look like: ```json { "data": { "items": { "schema": { "items": null, "requires_one_of": [ "table", "view" ], "has_items": false }, "table": { "items": null, "requires_one_of": null, "has_items": false }, "view": { "items": null, "requires_one_of": null, "has_items": false } }, "requires_one_of": [ "schema" ] } } ``` Next, we can drill down using the `requires_one_of` field recursively. For example: ```bash curl --request GET \ --url https://app.polytomic.com/api/connections/YOUR-CONNECTION-ID/target?type=schema \ --header "accept: application/json" \ --header "content-type: application/json" \ --header "X-Polytomic-Version: 2022-12-12" \ --header "Authorization: Bearer ${POLYTOMIC_API_KEY}" ``` The response will look like: ```json { "data": { "items": { "schema": { "items": [ "__pt_new_schema", "CUSTOMERS", "TEAMS" ], "requires_one_of": [ "table" ], "has_items": true }, "table": { "items": null, "requires_one_of": null, "has_items": false } }, "requires_one_of": [ "schema" ] } } ``` Notice, the schema also requires a table. We can enumerate those by adding to the query parameters. ```bash curl --request GET \ --url https://app.polytomic.com/api/connections/YOUR-CONNECTION-ID/target?type=table&search=CUSTOMERS \ --header "accept: application/json" \ --header "content-type: application/json" \ --header "X-Polytomic-Version: 2022-12-12" \ --header "Authorization: Bearer ${POLYTOMIC_API_KEY}" ``` The response will look like: ```json { "data": { "items": { "schema": { "items": null, "requires_one_of": [ "table" ], "has_items": false }, "table": { "items": [ "__pt_new_target", "CUSTOMERS.COMPANIES", "CUSTOMERS.CONTACTS" ], "requires_one_of": null, "has_items": true } }, "requires_one_of": [ "schema" ] } } ``` #### Query target fields The last step in enumerating a target for a sync is querying the available fields. To do this, we can POST a fields query on the target resource. ```bash curl --request POST \ --url https://app.polytomic.com/api/connections/YOUR-CONNECTION-ID/target/fields \ --header 'X-Polytomic-Version: 2022-12-12' \ --header "Authorization: Bearer ${POLYTOMIC_API_KEY}" \ --header 'content-type: application/json' \ -d '{"target": "CUSTOMERS.CONTACTS"}' ``` This response will show the available syncs modes as well as the fields and their associated metadata. For example: ```json { "data": { "id": "CUSTOMERS.CONTACTS", "name": "CUSTOMERS.CONTACTS", "modes": [{ "mode": "create", "description": "Create records when they don’t exist; don’t update existing ones", "label": "Create", "requires_identity": true, "supports_target_filters": false, "supports_field_sync_mode": false }, { "mode": "update", "description": "Update existing records only; don’t create new ones", "label": "Update", "requires_identity": true, "supports_target_filters": false, "supports_field_sync_mode": false }, { "mode": "updateOrCreate", "description": "Update records when they exist and create them when they don’t", "label": "Update or Create", "requires_identity": true, "supports_target_filters": false, "supports_field_sync_mode": false }, { "mode": "replace", "description": "Replace all existing rows", "label": "Replace", "requires_identity": false, "supports_target_filters": false, "supports_field_sync_mode": false }, { "mode": "append", "description": "Append rows to the end of the table", "label": "Append", "requires_identity": false, "supports_target_filters": false, "supports_field_sync_mode": false } ], "properties": { "supports_field_creation": true }, "refreshed_at": "0001-01-01T00:00:00Z", "fields": [{ "id": "EMAIL", "name": "EMAIL", "description": "", "required": false, "filterable": false, "createable": true, "updateable": true, "association": false, "supports_identity": true, "identity_functions": [ { "id": "Equality", "label": "Equality" } ], "source_type": "VARCHAR(16777216)", "type": "string" }, { "id": "FIRST_NAME", "name": "FIRST_NAME", "description": "", "required": false, "filterable": false, "createable": true, "updateable": true, "association": false, "supports_identity": true, "identity_functions": [ { "id": "Equality", "label": "Equality" } ], "source_type": "VARCHAR(16777216)", "type": "string" }, { "id": "LAST_NAME", "name": "LAST_NAME", "description": "", "required": false, "filterable": false, "createable": true, "updateable": true, "association": false, "supports_identity": true, "identity_functions": [ { "id": "Equality", "label": "Equality" } ], "source_type": "VARCHAR(16777216)", "type": "string" } ] } } ``` #### Setup sync mapping Finally, we can set up a mapping of fields from the model we created above and the target as seen below: ```bash curl --request POST \ --url https://app.polytomic.com/api/syncs \ --header 'X-Polytomic-Version: 2022-12-12' \ --header "Authorization: Bearer ${POLYTOMIC_API_KEY}" \ --header 'content-type: application/json' \ --data '{ "name": "MySQL to Snowflake Sync", "mode": "replace", "fields": [ { "source": { "field": "email", "model_id": "YOUR-SOURCE-MODEL-ID" }, "target": "EMAIL" }, { "source": { "field": "first_name", "model_id": "YOUR-SOURCE-MODEL-ID" }, "target": "FIRST_NAME" }, { "source": { "field": "last_name", "model_id": "YOUR-SOURCE-MODEL-ID" }, "target": "LAST_NAME" } ], "schedule": { "frequency": "manual" }, "target": { "connection_id": "YOUR-TARGET-CONNECTION-ID", "object": "CUSTOMERS.CONTACTS" } } ```