# Retrieve access token Source: https://docs.hotglue.com/api-reference/access-tokens/retrieve-access-token get /{env_id}/{flow_id}/{tenant}/connectors/{connector_id}/accesstoken Uses the tenant's linked credentials to retrieve a new access token for a given connector. Only supported on select connectors. Requires a secret API key, or a public API key with a tenant JWT passed via the `token` query parameter. # Authentication Source: https://docs.hotglue.com/api-reference/authentication ## API Keys All API requests require authentication using an API key. API keys are passed via the `x-api-key` header in your requests. ```shell theme={null} curl --request GET \ --url 'https://api.hotglue.com/...' \ --header 'x-api-key: your-api-key' ``` There are three types of API keys in hotglue: ### 1. Environment Secret API Key The Environment Secret API Key has global permissions on your environment. Only admins have access to view and manage this key. ### 2. Personal API Key Personal API Keys are tied to individual users and have permissions based on your role in a given environment. The available roles are: * **Admin** - Full permissions across all resources * **Developer** - Read and Write access to most resources * **Viewer** - Read-only access. Cannot read non-sensitive resources Personal API Keys are useful for programmatic access when you need permissions scoped to your user account. ### 3. Public API Key Public API Keys are used in your widget to request public resources. These keys are designed to be used in client-side applications and have limited permissions. ## JWT Authentication for Widgets In addition to using a Public API Key, you should configure your widget with a JWT and enable the "Require JWT to authenticate tenant requests" settings in the hotglue dashboard (**Settings > Widget**). When enabled, the Public API Key alone cannot be used to perform tenant-specific tasks --- a valid JWT must also be provided. ### Generate a Private Signing Key To generate your private signing key, head to the environment settings page and press **Generate private key** under the API Keys section: > [!WARNING] > > **Do not share this private signing key!** > > For security purposes, hotglue does not store your private signing key. Keys are unique to every hotglue environment and can only be generated by an admin. Store this private signing key securely in your backend environment variables. ### Creating a JWT Once you have a private signing key, you can generate a JWT from your backend to make secure requests to the hotglue API. In JavaScript, you can do this with: ```javascript theme={null} const jsonwebtoken = require('jsonwebtoken'); const currentTime = Math.floor(Date.now() / 1000); const tenantId = "unique-tenant-identifier"; const token = jsonwebtoken.sign( { sub: tenantId, iat: currentTime, exp: currentTime + (60 * 60), // 1 hour from now }, Buffer.from(process.env['HOTGLUE_SIGNING_KEY'], "base64").toString("utf8"), { algorithm: "RS256", } ); ``` ### Scoping a JWT You can limit what a JWT is allowed to do by adding an optional `scopes` claim. * **No `scopes` claim:** the JWT keeps full tenant access, exactly as before. * **With a `scopes` claim:** it must be a list of strings, and it must include every scope the endpoint requires. ```javascript theme={null} const token = jsonwebtoken.sign( { sub: tenantId, iat: currentTime, exp: currentTime + (60 * 60), scopes: ["linked_connector.read", "jobs.read"], }, Buffer.from(process.env['HOTGLUE_SIGNING_KEY'], "base64").toString("utf8"), { algorithm: "RS256", } ); ``` Here are examples of common scopes that apply to tenant endpoints: | Scope | Grants | | - | - | | `linked_connector.read` | List a tenant's linked sources, targets and connectors | | `linked_connector.write` | Link and update a tenant's sources, targets and connectors | | `linked_connector.delete` | Unlink a tenant's sources, targets and connectors | | `linked_connector_catalog.read` | Include the catalog when listing linked connectors (`?catalog=true`) | | `linked_connector_secrets.read` | Include credentials when returning a linked connector's config. Without it, secrets are left out | | `connector_metadata.read` | Include connector metadata when listing linked sources (`?metadata=true`) | | `connector_state.delete` | Reset a linked connector's state | | `discover.read` | Poll a discover run | | `discover.write` | Start a discover run | | `jobs.read` | List jobs and read job status | | `schedule.read` | Read a tenant's job schedule | | `tenant_mapping.read` | Read a tenant's mapping | | `tenant_mapping.write` | Update a tenant's mapping | ### Using the JWT in Widget V3 When using Widget V3 with React, you can pass the JWT directly to the `useHotglue` hook: ```jsx theme={null} import { useHotglue, Widget } from "@hotglue/widget"; export default function WidgetLauncher() { const tenantId = "MY-TENANT-ID"; // Generate the JWT in your backend using the signing key const jwt = getJwt(); const { openWidget } = useHotglue({ tenantId, environmentId: process.env.NEXT_PUBLIC_HOTGLUE_ENV_ID, apiKey: process.env.NEXT_PUBLIC_HOTGLUE_PUBLIC_KEY, jwtToken: '' }); return (
); } ``` ### Using the JWT in Widget V2 When launching the widget, you can pass the JWT using the [options parameter](https://docs.hotglue.com/docs/embed-hotglue-javascript-reference#options): ```javascript theme={null} // Generate the JWT in your backend using the signing key const jwt = getJwt(); // Launch the widget HotGlue.open("tenant-id", { jwtToken: jwt }); ``` For vanilla JavaScript, you can pass the JWT when initializing the `Hotglue` instance: ```javascript theme={null} // Generate the JWT in your backend using the signing key const jwt = getJwt(); const hotglue = new Hotglue({ tenantId: 'tenant-123', environmentId: '', apiKey: '', jwtToken: '' }); ``` ### Using the JWT in API Requests Tenant-scoped API endpoints allow you to pass the JWT as a bearer token to access data on behalf of a tenant while using your Public API Key: ```shell theme={null} curl --request GET \ --url 'https://api.hotglue.com/env_id/flow_id/tenant_id/linkedSources' \ --header 'Accept: application/json' \ --header 'x-api-key: public_api_key' \ --header 'Authorization: Bearer ``` # Create linked flows Source: https://docs.hotglue.com/api-reference/flows/create-linked-flows post /{env_id}/flows/linked Link a flow for a specific tenant # Retrieve linked flows Source: https://docs.hotglue.com/api-reference/flows/retrieve-linked-flows get /{env_id}/flows/linked Returns the flows that are currently linked for a specific tenant # Retrieve supported flows Source: https://docs.hotglue.com/api-reference/flows/retrieve-supported-flows get /{env_id}/flows/supported Returns all flows in an environment and their connectors # Cancel queued job Source: https://docs.hotglue.com/api-reference/jobs/cancel-queued-job delete /{env_id}/{flow}/{user_id}/jobs/queued/{queued_job_id} Cancels a queued job. # Fetch environment queued jobs Source: https://docs.hotglue.com/api-reference/jobs/fetch-environment-queued-jobs get /{env_id}/jobs/queued Returns queued jobs for an environment across flows/users. # Fetch job zip Source: https://docs.hotglue.com/api-reference/jobs/fetch-job-zip get /{env_id}/{flow_id}/{tenant}/jobs/zip Jobs Download # Fetch jobs Source: https://docs.hotglue.com/api-reference/jobs/fetch-jobs get /{env_id}/{flow_id}/{tenant}/jobs Returns a list of job details for a specified tenant. Note that this endpoint does not return raw data fetched in jobs. # Fetch queued jobs Source: https://docs.hotglue.com/api-reference/jobs/fetch-queued-jobs get /{env_id}/{flow}/{user_id}/jobs/queued Returns queued jobs for a specific environment, flow, and user/tenant. # Stage data for write jobs Source: https://docs.hotglue.com/api-reference/jobs/generate-upload-url post /{env_id}/{flow}/{user_id}/connectors/api/uploads/url Generates a presigned URL for uploading a JSON file to a connector's uploads directory. Upload the file to the returned URL, then trigger a write job to process it. Instead of uploading your records in the POST job requests (which is subject to payload size limits), you can use this endpoint to stage records of arbitrary size. After generating your presigned url, you can upload json records: ```bash theme={null} # Upload your data curl --request PUT \ --url "$PRESIGNED_URL" \ --header 'Content-Type: application/json' \ --data '{ "Contacts": [ { "email": "testemail@hg.io", "id": "5634", "name": "John Doe" }, { "email": "testemailtwo@hg.io", "id": "6634", "name": "Jane Doe" } ] }' # Trigger a write job (no state body — the job reads the staged file) curl --request POST \ --url 'https://api.hotglue.com/v2/{env_id}/{flow_id}/{tenant}/jobs' \ --header 'content-type: application/json' \ --header 'x-api-key: ' \ --data '{ "connector_id": "hubspot", "job_type": "write", }' ``` # Get latest job Source: https://docs.hotglue.com/api-reference/jobs/get-latest-job get /{env_id}/{flow_id}/{tenant}/jobs/latest Fetch the most recent job for a given tenant in a given flow # Kill job Source: https://docs.hotglue.com/api-reference/jobs/kill-job post /{env_id}/{flow_id}/{tenant}/jobs/kill End any running processes for a job. Provide exactly one of `job_root`, `job_id`, or `external_job_id`. # Poll job status Source: https://docs.hotglue.com/api-reference/jobs/poll-job-status get /{env_id}/{flow_id}/{tenant}/jobs/status Check on the status of a job using exactly one of `job_root`, `job_id`, or `external_job_id`. Read about the possible job statuses [here](/key-concepts/jobs/life-cycle). # Retrigger a job Source: https://docs.hotglue.com/api-reference/jobs/retrigger-job post /{env_id}/{flow}/{tenant_id}/jobs/retrigger Retriggers a job based on exactly one of the provided job_root, job_id, or external_job_id and parameters. Returns the job details for the retriggered job. # Rollback job Source: https://docs.hotglue.com/api-reference/jobs/rollback-job post /{env_id}/{flow_id}/{tenant}/jobs/rollback Reset the the configuration to the state before a given job ran. This affects the `source state` (bookmarks) and the `snapshots`. # Trigger download Source: https://docs.hotglue.com/api-reference/jobs/trigger-download get /{env_id}/{flow_id}/{tenant}/jobs/download Jobs Download # Create a Magic Link Source: https://docs.hotglue.com/api-reference/manage-tenants/create-magic-link post /{env_id}/magicLink Create a Magic Link to allow tenants to link an integration. # Delete a tenant Source: https://docs.hotglue.com/api-reference/manage-tenants/delete-a-tenant delete /tenant/{env_id}/{tenant} Delete all of a tenants data and optionally revoke OAuth connections # Delete Snapshot Source: https://docs.hotglue.com/api-reference/manage-tenants/delete-snapshot delete /tenant/{env_id}/{tenant}/snapshots Delete all existing snapshots for a particular tenant Learn more about snapshots [here](/transformation/snapshots). # Get Snapshots Source: https://docs.hotglue.com/api-reference/manage-tenants/get-snapshot get /tenant/{env_id}/{tenant}/snapshots Retrieve either a list of snapshot files or a specific snapshot file for a tenant. Learn more about snapshots [here](/transformation/snapshots). # Get tenant config Source: https://docs.hotglue.com/api-reference/manage-tenants/get-tenant-config get /tenant/{env_id}/{tenant}/config Gets the `tenant-config.json` from snapshots # Get tenant mapping Source: https://docs.hotglue.com/api-reference/manage-tenants/get-tenant-mapping get /tenant/{env_id}/{tenant}/mapping Gets the mapping object from the `tenant-config.json`, if present # Retrieve tenants Source: https://docs.hotglue.com/api-reference/manage-tenants/retrieve-tenants get /tenants/{env_id} Returns a list of tenants that exist in an environment # Set tenant config Source: https://docs.hotglue.com/api-reference/manage-tenants/set-tenant-config put /tenant/{env_id}/{tenant}/config Creates a `tenant-config.json` that you can use to store custom settings, credentials, and metadata # Set tenant mapping Source: https://docs.hotglue.com/api-reference/manage-tenants/set-tenant-mapping put /tenant/{env_id}/{tenant}/mapping Adds a mapping object to the `tenant-config.json`. You can use the **Set Tenant Mapping** endpoint to apply a mapping without using the mapping widget. > [!NOTE] > > If the **Update Fields on Mapping** widget setting is enabled, the optional `entityType`, `entityId`, and `flow` params are required. Below is an example body: ```json theme={null} { "config": { "mapping": { "": { "/": { "": "" } } } }, "entityType": "taps", // optional - `taps` or `connectors` "entityId": "salesforce", // optional "flow": "FElWoODnU" // optional } ``` # Set tenant metadata Source: https://docs.hotglue.com/api-reference/manage-tenants/set-tenant-metadata put /tenant/{env_id}/{tenant}/metadata Add metadata to your [Tenant Metadata](/key-concepts/tenants/metadata) object # Toggle schedule Source: https://docs.hotglue.com/api-reference/manage-tenants/toggle-schedule put /tenants/{env_id}/schedule Disable, enable, and manage schedules across tenants in your environment # Update tenant config Source: https://docs.hotglue.com/api-reference/manage-tenants/update-tenant-config patch /tenant/{env_id}/{tenant}/config Update an existing tenant config # Generate MCP token Source: https://docs.hotglue.com/api-reference/mcp/generate-mcp-token get /{env_id}/{flow_id}/{tenant}/mcpToken Generates a per-tenant bearer token for authenticating to hotglue's Composite MCP server (`https://composite-mcp.hotglue.com/mcp`). The token scopes tool discovery and tool calls to the specified tenant's linked connectors. # Overview Source: https://docs.hotglue.com/api-reference/overview Start making requests to the hotglue API! To start using the hotglue API, make sure you have the following handy ## Environment ID ### (env\_id) This is the ID of your hotglue environment. It can be found in the hotglue panel, under the settings page. ## API Key ### (x-api-key) This is your public or private API key, depending on the sensitivity of your request. It can be found in the hotglue panel, under the settings page. By default, this is global to all your hotglue environments. [Learn more](/api-reference/authentication) about authenticating to the hotglue API. ## Flow ID ### (flow\_id) If you're working with a specific flow, you will need to know its ID. This is available in the URL when you're in a specific flow, or can be requested via API. # Poll write request Source: https://docs.hotglue.com/api-reference/real-time/status get /{env_id}/{flow_id}/{tenant}/connectors/status If a real-time write request returns async: true, you can use this endpoint to get the result of the request. # Write to a connector Source: https://docs.hotglue.com/api-reference/real-time/write post /{env_id}/{flow_id}/{tenant}/connectors/{connector_id}/{stream} Write data directly to integrations in real-time. Note: this feature is in beta with limited support. # Create jobs schedule Source: https://docs.hotglue.com/api-reference/schedule-jobs/create-jobs-schedule put /{env_id}/{flow_id}/{tenant}/jobs/schedule Create a new schedule for a tenant # Delete jobs schedule Source: https://docs.hotglue.com/api-reference/schedule-jobs/delete-jobs-schedule delete /{env_id}/{flow_id}/{tenant}/jobs/schedule Delete or disable a schedule for a tenant > [!NOTE] > > **Hard delete is only supported for the default tenant.** When `hard_delete=true` and `tenant` is `default`, the schedule is permanently removed. For any other tenant, the same request only disables the schedule — it does not delete it. > > See [Deleting or disabling schedules via API](/key-concepts/jobs/scheduling#deleting-or-disabling-schedules-via-api) for details. # Retrieve jobs schedule Source: https://docs.hotglue.com/api-reference/schedule-jobs/retrieve-jobs-schedule get /{env_id}/{flow_id}/{tenant}/jobs/schedule Fetch the schedule for a tenant # Delete Connector Selected Filters Source: https://docs.hotglue.com/api-reference/stream-filters/delete-selected-filters delete /{env_id}/{flow_id}/{tenant}/connectors/{connector_id}/selectedFilters Delete the Connector Selected Filters configuration # Retrieve Connector Available Filters Source: https://docs.hotglue.com/api-reference/stream-filters/get-available-filters get /{env_id}/{flow_id}/{tenant}/connectors/{connector_id}/availableFilters Fetch the Available Filters configuration for a connector # Retrieve Connector Selected Filters Source: https://docs.hotglue.com/api-reference/stream-filters/get-selected-filters get /{env_id}/{flow_id}/{tenant}/connectors/{connector_id}/selectedFilters Fetch the Connector Selected Filters configuration # Save Connector Selected Filters Source: https://docs.hotglue.com/api-reference/stream-filters/put-selected-filters put /{env_id}/{flow_id}/{tenant}/connectors/{connector_id}/selectedFilters Save the Connector Selected Filters configuration # Introduction Source: https://docs.hotglue.com/api-reference/v1/introduction The following endpoints apply for V1, one-way flows Flows define a group of integrations that your customers can connect to. There are three types of flows that you can enable in hotglue: ## V1 - One-way flows ### Source flow This is the simplest way to use hotglue, and the default flow type when you toggle off **bidirectional flows**. With a source flow, your customer connects the `source` or `tap`, and you read data in from those linked sources into your own default target. ### Target flow This can be enabled in the **General** tab of a V1 flow. This is the inverse of a source flow, where your customer links an integration that you write data out to, but cannot read data in from. ## V2 - bidirectional flows If you need to read and write data to the same integration, you can use a bidirectional flow to use the same connection for both. There are two main differences between API calls for V1 and V2 flows: * V2 flows include a `/v2` in API calls. * V2 flows do not have a concept of `taps` and `targets`. From the perspective of a V2 flow, everything is a `connector`. # Run a V1 job Source: https://docs.hotglue.com/api-reference/v1/jobs/run-job post /{env_id}/{flow_id}/{tenant}/jobs Kicks off a job for a given tenant. When using the API tap, you can pass a payload in the `state` object to be written to the target. When `queue_if_active_job` is set to true in the request body, hotglue queues the job if another job is already running for the same tenant or flow. # Delete source state Source: https://docs.hotglue.com/api-reference/v1/linked-sources-state/delete-source-state delete /{env_id}/{flow_id}/{tenant}/linkedSources/state Clearing the source state means that the next job will be a full sync # Retrieve source state Source: https://docs.hotglue.com/api-reference/v1/linked-sources-state/retrieve-source-state get /{env_id}/{flow_id}/{tenant}/linkedSources/state Fetch the current bookmarks for your tenant's linked source # Set source state Source: https://docs.hotglue.com/api-reference/v1/linked-sources-state/set-source-state put /{env_id}/{flow_id}/{tenant}/linkedSources/state Overwrite the source state with your own bookmarks to re-sync or ignore data # Kill discover Source: https://docs.hotglue.com/api-reference/v1/linked-sources/kill-discover get /{env_id}/{flow_id}/{tenant}/linkedConnectors/discover/kill # Link a source Source: https://docs.hotglue.com/api-reference/v1/linked-sources/link-a-source post /{env_id}/{flow_id}/{tenant}/linkedSources Create a new connection for a tenant by passing a config object, along with an optional schedule or field_map # Poll Discover Source: https://docs.hotglue.com/api-reference/v1/linked-sources/poll-discover get /{env_id}/{flow_id}/{tenant}/linkedSources/discover/poll Check the status of a running discover. If empty, no discover is currently running. # Retrieve linked source Source: https://docs.hotglue.com/api-reference/v1/linked-sources/retrieve-linked-source get /{env_id}/{flow_id}/{tenant}/linkedSources Fetch the linked source for a tenant. This can be useful for fetching credentials and flags, and to confirm that a user is properly connected. # Run Discover Source: https://docs.hotglue.com/api-reference/v1/linked-sources/run-discover get /{env_id}/{flow_id}/{tenant}/linkedSources/discover Run a discover to generate a `catalog` of available tables and fields # Unlink a source Source: https://docs.hotglue.com/api-reference/v1/linked-sources/unlink-a-source delete /{env_id}/{flow_id}/{tenant}/linkedSources Permanently delete your tenant's connection. This cannot be undone. # Update linked sources Source: https://docs.hotglue.com/api-reference/v1/linked-sources/update-linked-sources patch /{env_id}/{flow_id}/{tenant}/linkedSources Modify the field map or change the config for a linked source # Link a target Source: https://docs.hotglue.com/api-reference/v1/linked-targets/link-a-target post /{env_id}/{flow_id}/{tenant}/linkedTargets Link one of your tenants to a target # Retrieve linked target Source: https://docs.hotglue.com/api-reference/v1/linked-targets/retrieve-linked-target get /{env_id}/{flow_id}/{tenant}/linkedTargets Fetch metadata about your tenant's linked target # Run Discover Source: https://docs.hotglue.com/api-reference/v1/linked-targets/run-discover get /{env_id}/{flow_id}/{tenant}/linkedTargets/discover Run a discover for a linked target # Unlink a target Source: https://docs.hotglue.com/api-reference/v1/linked-targets/unlink-a-target delete /{env_id}/{flow_id}/{tenant}/linkedTargets Clears the configuration for a tenant's linked target. This cannot be undone. # Update a linked target Source: https://docs.hotglue.com/api-reference/v1/linked-targets/update-linked-target patch /{env_id}/{flow_id}/{tenant}/linkedTargets Modify the config object on a linkedTarget # Available sources Source: https://docs.hotglue.com/api-reference/v1/source-metadata/available-sources get /{env_id}/availableSources Returns details for every source that you can enable in your environment # Supported sources Source: https://docs.hotglue.com/api-reference/v1/source-metadata/supported-sources get /{env_id}/{flow_id}/supportedSources Returns all of the sources that are enabled in a particular flow # Available targets Source: https://docs.hotglue.com/api-reference/v1/target-metadata/available-targets get /{env_id}/availableTargets Returns details for every target that you can enable in your environment # Supported targets Source: https://docs.hotglue.com/api-reference/v1/target-metadata/supported-targets get /{env_id}/{flow_id}/supportedTargets Returns all of the targets that are enabled in a particular flow # Poll connector metadata refresh Source: https://docs.hotglue.com/api-reference/v2/connector-metadata/poll-connector-metadata get /{env_id}/{flow}/{user_id}/connectors/{connector_id}/metadata/poll Check the status of a connector metadata refresh. # Refresh connector metadata Source: https://docs.hotglue.com/api-reference/v2/connector-metadata/refresh-connector-metadata post /{env_id}/{flow}/{user_id}/connectors/{connector_id}/metadata/refresh Start a metadata refresh for a linked connector. # Retrieve available connectors Source: https://docs.hotglue.com/api-reference/v2/connector-metadata/retrieve-available-connectors get /v2/{env_id}/availableConnectors Returns details for every connector that you can enable in your environment # Retrieve connector metadata Source: https://docs.hotglue.com/api-reference/v2/connector-metadata/retrieve-connector-metadata get /{env_id}/{flow}/{user_id}/connectors/{connector_id}/metadata Retrieve the metadata stored for a linked connector. # Retrieve supported connectors Source: https://docs.hotglue.com/api-reference/v2/connector-metadata/retrieve-supported-connectors get /v2/{env_id}/{flow_id}/supportedConnectors Returns details for connectors that have been enabled in a given flow # Introduction Source: https://docs.hotglue.com/api-reference/v2/introduction The following section applies to V2 bidirectional flows. Flows define a group of integrations that your customers can connect to. There are three types of flows that you can enable in hotglue: ## V1 - One-way flows ### Source flow This is the simplest way to use hotglue, and the default flow type when you toggle off **bidirectional flows**. With a source flow, your customer connects the `source` or `tap`, and you read data in from those linked sources into your own default target. ### Target flow This can be enabled in the **General** tab of a V1 flow. This is the inverse of a source flow, where your customer links an integration that you write data out to, but cannot read data in from. ## V2 - bidirectional flows If you need to read and write data to the same integration, you can use a bidirectional flow to use the same connection for both. There are two main differences between API calls for V1 and V2 flows: * V2 flows include a `/v2` in API calls. * V2 flows do not have a concept of `taps` and `targets`. From the perspective of a V2 flow, everything is a `connector`. # Run a V2 Job Source: https://docs.hotglue.com/api-reference/v2/jobs/create post /v2/{env_id}/{flow_id}/{tenant}/jobs Kicks off a job for a given tenant. Can be used to write data in target flows by passing a payload in the state object. When `queue_if_active_job` is set to true in the request body, hotglue queues the job if another job is already running for the same tenant or flow. # Delete connector state Source: https://docs.hotglue.com/api-reference/v2/linked-connectors-state/delete-connector-state delete /v2/{env_id}/{flow_id}/{tenant}/linkedConnectors/state Clearing the connector state means that the next job will be a full sync # Retrieve connector state Source: https://docs.hotglue.com/api-reference/v2/linked-connectors-state/retrieve-connector-state get /v2/{env_id}/{flow_id}/{tenant}/linkedConnectors/state Fetch the current bookmarks for your tenant's linked connector # Set connector state Source: https://docs.hotglue.com/api-reference/v2/linked-connectors-state/set-connector-state put /v2/{env_id}/{flow_id}/{tenant}/linkedConnectors/state Overwrite the connector state with your own bookmarks to re-sync or ignore data # Link a connector Source: https://docs.hotglue.com/api-reference/v2/linked-connectors/create post /v2/{env_id}/{flow_id}/{tenant}/linkedConnectors Create a new connection for your tenant, along with an optional schedule and field map, without using the embedded widget. # Unlink connector Source: https://docs.hotglue.com/api-reference/v2/linked-connectors/delete delete /v2/{env_id}/{flow_id}/{tenant}/linkedConnectors Clear the credentials and configuration for a tenant's linked integration. This cannot be undone. # Retrieve linked connector Source: https://docs.hotglue.com/api-reference/v2/linked-connectors/get get /v2/{env_id}/{flow_id}/{tenant}/linkedConnectors Fetch the configuration details for a linked connector # Poll Discover Source: https://docs.hotglue.com/api-reference/v2/linked-connectors/poll-discover-status get /v2/{env_id}/{flow_id}/{tenant}/linkedConnectors/discover/poll Check the status of a running discover. If empty, no discover is currently running. # Run Discover Source: https://docs.hotglue.com/api-reference/v2/linked-connectors/trigger-discover get /v2/{env_id}/{flow_id}/{tenant}/linkedConnectors/discover Run a discover to generate a `catalog` of available tables and fields # Update linked connectors Source: https://docs.hotglue.com/api-reference/v2/linked-connectors/update patch /v2/{env_id}/{flow_id}/{tenant}/linkedConnectors Modify the field map or change the config for a linked connector # Unlink a source Source: https://docs.hotglue.com/api-reference/v2/linked-sources/delete delete /v2/{env_id}/{flow_id}/{tenant}/linkedSources Permanently delete your tenant's linked source connection. This will revoke OAuth credentials and remove the source configuration. This cannot be undone. # Get linked sources Source: https://docs.hotglue.com/api-reference/v2/linked-sources/get get /v2/{env_id}/{flow_id}/{tenant}/linkedSources Get a linked source's configuration, catalog, secrets, and trigger mapping for a V2 flow # Update linked source Source: https://docs.hotglue.com/api-reference/v2/linked-sources/update patch /v2/{env_id}/{flow_id}/{tenant}/linkedSources Update a linked source # Unlink a target Source: https://docs.hotglue.com/api-reference/v2/linked-targets/delete delete /v2/{env_id}/{flow_id}/{tenant}/linkedTargets Permanently delete your tenant's linked target connection. This will revoke OAuth credentials and remove the target configuration. This cannot be undone. # Get linked targets Source: https://docs.hotglue.com/api-reference/v2/linked-targets/get get /v2/{env_id}/{flow_id}/{tenant}/linkedTargets Returns the targets linked by a user_id in this env_id # Update linked target Source: https://docs.hotglue.com/api-reference/v2/linked-targets/update patch /v2/{env_id}/{flow_id}/{tenant}/linkedTargets Update a linked target # Configuration Source: https://docs.hotglue.com/cli/configuration The hotglue CLI derives its configuration from two places: the **Profile config** and the **Project config**. ## Profile config The Profile config is stored in a `config.yaml` file located at `$HOME/.hotglue/`. At the moment, it is only used to store your `apikey`. ## Project config The Project config is stored in a hotglue rc-like file and can be created anywhere in your project's folder structure. A Project settings file can hold any of the CLI's parameters (including overriding the apikey, although this is not recommended) and is used to define configuration values specific for that context. The configuration files can use any of the following names: `hotglue.yaml`, `.hotglue.yaml`, `.hotgluerc.yaml`, `.hotgluerc.yml`, `.hotgluerc`, `.hotgluerc.json`, `.hotgluerc.js` As the extensions suggest, the files support either yaml, json or js syntax (in case of JS, the config object has to be exported). However, we recommend using the yaml format. ## Configure your environment [](https://docs.hotglue.com/docs/cli-configuration#configure-your-environment) ### Set API Key [](https://docs.hotglue.com/docs/cli-configuration#set-api-key) To start, you'll need to get your **Personal API Key** from \_**[Account](https://hotglue.xyz/app/settings%5D) > Login & Security > Personal API Key\***, as shown below: ![3068](https://files.readme.io/906edaa-Hotglue_personal_settings.png) ### Personal API Key Once you have this, you can save the API Key to your **Profile config** `$ hotglue config set apikey ` ### Project settings [](https://docs.hotglue.com/docs/cli-configuration#project-settings) Once you have this done, you can create your Project config. For this example, I'll use the yaml syntax and a file named `.hotgluerc`. This config can include the following parameters: | Option | Description | | - | - | | `env` | Specify your hotglue **environment id** (ie. `dev.hotglue.acme.com`) | | `flow` | Specify your hotglue **flow id** (ie. `MDKdfumqM`) | | `tap` | Specify the **tap** to use for the hotglue commands. (ie. `salesforce`) | | `tenant` | Optional. The **tenant id** to use for the commands. Defaults to `default`, the admin config. | Here's a sample config based on the examples listed above: ```shell .hotgluerc theme={null} env: dev.hotglue.acme.com flow: MDKdfumqM tap: salesforce ``` You can now verify your config was created successfully using the `hotglue config` command: ```shell theme={null} $ hotglue config ┌─────────┬───────────────────────────┬─────────────────────────────────────────┬─────────┐ │ Setting │ Value │ Config File │ Type │ ├─────────┼───────────────────────────┼─────────────────────────────────────────┼─────────┤ │ apikey │ ************************ │ /.hotglue/config.yaml │ Profile │ ├─────────┼───────────────────────────┼─────────────────────────────────────────┼─────────┤ │ env │ dev.hotglue.acme.com │ .hotgluerc │ Project │ ├─────────┼───────────────────────────┼─────────────────────────────────────────┼─────────┤ │ flow │ MDKdfumqM │ .hotgluerc │ Project │ ├─────────┼───────────────────────────┼─────────────────────────────────────────┼─────────┤ │ tap │ salesforce │ .hotgluerc │ Project │ ├─────────┼───────────────────────────┼─────────────────────────────────────────┼─────────┤ │ tenant │ default │ .hotgluerc │ Project │ └─────────┴───────────────────────────┴─────────────────────────────────────────┴─────────┘ ``` ## Project structure [](https://docs.hotglue.com/docs/cli-configuration#project-structure) When developing transformation scripts, we recommend a project structure similar to the following, so you can easily deploy scripts for multiple sources with ease. Note that each folder contains a unique `.hotgluerc` which reference different sources (and can even reference different flows). ``` ├── salesforce │ ├── etl.ipynb │ └── .hotgluerc ├── hubspot │ ├── etl.ipynb │ └── .hotgluerc ├── pipedrive │ ├── etl.ipynb │ └── .hotgluerc ``` # Env Source: https://docs.hotglue.com/cli/env List environments, create available connectors, and manage environment settings with the hotglue CLI Use the `env` commands to list accessible environments and manage environment settings. Environment settings include `requirements.txt`, `availableSources.json`, `availableTargets.json`, `availableConnectors.json`, and `customTaps.json`. Use `env connector` to create [available connectors](/key-concepts/connectors/connectors#what-is-an-available-connector) for an environment. After a connector is available, add it to a flow with [`supported-entities create`](/cli/supported-entities#supported-entities-create). # Env List ## Description Lists the environments available to your Personal API Key. Configure the key with `hotglue config set apikey ` or pass it with `--apikey`. Unlike other environment commands, `env list` does not require `--env`. ## Sample ```shell theme={null} hotglue env list hotglue env list --json ``` Environment API keys are omitted by default. Use `--include-secrets` to include them in the output. ```shell theme={null} hotglue env list --include-secrets ``` Secret-enabled output uses these field names: * `publicApiKey`: the environment's public API key * `personalApiKey`: your Personal API Key * `environmentApiKey`: the environment API key, when authorized `--include-secrets` may print your Personal API Key. Do not expose its output in logs, CI output, or shared terminals. ## Parameters | Option | Default | Description | | - | - | - | | `--apikey`, `-k` | Profile config | Personal API Key used to authenticate the request. | | `--json` | `false` | Return machine-readable JSON output. | | `--include-secrets` | `false` | Include sensitive API key fields in the output. | # Available environment settings | File | Description | | - | - | | `requirements.txt` | Default Python dependencies to be used in ETL Scripts | | `availableSources.json` | List of customized sources available in V1 Flows | | `availableTargets.json` | List of customized targets available in V1 Flows | | `availableConnectors.json` | List of customized connectors available in V2 Flows | | `customTaps.json` | List of custom taps built with Hotglue's Connector Builder | # Env Connector Create ## Description Creates a new available connector for the environment and appends it to `availableConnectors.json`. The connector id must not already exist in the environment. `--read-install-uri` is mapped onto `read_connector.install_uri`. If you pass `--write-install-uri`, it is mapped onto `write_connector.install_uri`. Passing `--auth-url` or `--token-url` sets the connector `type` to `oauth`. ## Samples Create an API-key connector with flags: ```shell theme={null} hotglue env connector create \ --env prod.acme.com \ --id my-connector \ --label "My Connector" \ --read-install-uri "git+https://github.com/org/tap-example.git" \ --connect-ui-params '{"api_key":{"label":"API Key","type":"password"}}' ``` Include a write connector install URI: ```shell theme={null} hotglue env connector create \ --env prod.acme.com \ --id my-connector \ --label "My Connector" \ --read-install-uri "git+https://github.com/org/tap-example.git" \ --write-install-uri "git+https://github.com/org/target-example.git" ``` Create an OAuth connector: ```shell theme={null} hotglue env connector create \ --env prod.acme.com \ --id my-connector \ --label "My Connector" \ --read-install-uri "git+https://github.com/org/tap-example.git" \ --auth-url "https://example.com/oauth/authorize" \ --token-url "https://example.com/oauth/token" ``` Return machine-readable output: ```shell theme={null} hotglue env connector create \ --env prod.acme.com \ --id my-connector \ --label "My Connector" \ --read-install-uri "git+https://github.com/org/tap-example.git" \ --json ``` ## Parameters | Option | Default | Description | | - | - | - | | `--apikey`, `-k` | Profile config | Personal API Key used to authenticate the request. | | `--env`, `-e` | | **Required.** Environment to create the available connector in. | | `--id` | | **Required.** Unique connector id. | | `--label` | | **Required.** Display name for the connector. | | `--read-install-uri` | | **Required.** Install URI for the read connector. | | `--write-install-uri` | | Install URI for the write connector. | | `--connect-ui-params` | | Shell-quoted JSON object defining Connect UI params for API credentials. | | `--auth-url` | | OAuth authorize URL. | | `--token-url` | | OAuth token URL. | | `--json` | `false` | Return machine-readable output. | # Env Download ## Description Clones the remote env settings saved in Hotglue to your local machine. ## Sample ```shell theme={null} $ hotglue env download [--downloadTo] ✔ Finished: Verifying user and authorizing. ✔ Finished: Scanning environment dev.hotglue.acme.com. ℹ Info: Downloading to ./projects/cin7. ✔ Finished: Downloading file: requirements.txt. ┌──────────────────┬────────────┐ │ File │ Status │ ├──────────────────┼────────────┤ │ requirements.txt │ Downloaded │ └──────────────────┴────────────┘ ``` ## Parameters | Option | Default | Description | | - | - | - | | `--downloadTo` | | | | `-d` | `.` | The directory to download the files to. Defaults to the local directory. | # Env Deploy ## Description Deploys your environment settings ## Sample ```shell theme={null} $ hotglue env deploy [--sourceFolder] ✔ Finished: Scanning ./projects/cin7 for deployable files. ✔ Finished: Verifying user and authorizing. ℹ Info: Deploying environment files. ✔ Finished: Pushing file: requirements.txt. ┌──────────────────┬──────────┐ │ File │ Status │ ├──────────────────┼──────────┤ │ requirements.txt │ Deployed │ └──────────────────┴──────────┘ ``` ## Parameters | Option | Default | Description | | - | - | - | | `--sourceFolder` | | | | `-s` | `.` | The directory to upload the files from. Defaults to the local directory. | # ETL Source: https://docs.hotglue.com/cli/etl hotglue CLI commands for ETL Programmatically manage your transformation scripts using the `etl` commands below. # ETL Download ### Description Clones the remote ETL script saved in hotglue to your local machine. ### Sample ```shell theme={null} $ hotglue etl download [--overwrite] [--downloadTo] ✔ Finished: Verifying user and authorizing. ✔ Finished: Scanning for downloadable files. ℹ Info: Downloading script files to ./scripts/tap. ✔ Finished: Downloading file: etl.ipynb. ┌───────────┬────────────┐ │ File │ Status │ ├───────────┼────────────┤ │ etl.ipynb │ Downloaded │ └───────────┴────────────┘ ``` ### Parameters | Option | Default | Description | | - | - | - | | `--overwrite` | | | | `-o` | `false` | When enabled, overwrites any files that already exist locally in the download to directory. | | `--downloadTo` | | | | `-d` | `.` | The directory to download the ETL to. Defaults to the local directory. | # ETL Deploy ### Description Deploys the local ETL script to hotglue. ### Sample [](https://docs.hotglue.com/docs/cli-etl#sample-1) ``` $ hotglue etl deploy [--sourceFolder] ✔ Finished: Verifying user and authorizing. ✔ Finished: Validating flow and tap location. ✔ Finished: Preparing deployment target. ℹ Info: Deploying ETL scripts. ✔ Finished: Pushing file: default/flows/bTHIweD0W/taps/cin7/etl/etl.ipynb. ┌─────────────────────────────────────────────────┬──────────┐ │ File │ Status │ ├─────────────────────────────────────────────────┼──────────┤ │ default/flows/bTHIweD0W/taps/cin7/etl/etl.ipynb │ Deleted │ ├─────────────────────────────────────────────────┼──────────┤ │ default/flows/bTHIweD0W/taps/cin7/etl/etl.ipynb │ Deployed │ └─────────────────────────────────────────────────┴──────────┘ ``` ### Parameters | Option | Default | Description | | - | - | - | | `--sourceFolder` | | | | `-s` | `.` | The directory to upload the ETL script from. Defaults to the local directory. | # ETL Delete ### Description Deletes a deployed ETL script on hotglue. ### Sample ```shell theme={null} $ hotglue etl delete ℹ Info: Deleting ETL scripts for Tenant tenantId Flow flowId and Tap tapId to envId. ✔ Finished: Verifying user and authorizing. ✔ Finished: Deleting ETL scripts. ┌───────────┬─────────┐ │ File │ Status │ ├───────────┼─────────┤ │ etl.ipynb │ Deleted │ └───────────┴─────────┘ ``` # ETL Set up Local Job Data ### Description Clones hotglue job data to your local machine and creates a `.env` file with the job's environment variables. The file structure and content is identical to the file system your ETL script ran in. The downloaded `etl-output` folder will be renamed to `etl-output-reference`\ and the `snapshots` folder will be renamed to `snapshots-reference`. We recommend using this command to reproduce ETL failures or back test again successful jobs. ### Sample ```shell theme={null} $ hotglue etl setup-local-run tenant123/flows/At_kHalC/jobs/2026/02/09/05/7Y6iUA [--include-configs] [--overwrite] [--downloadTo] ✔ Finished: Verifying user and authorizing. ✔ Finished: Scanning for downloadable files. ┌───────────────────────────────┬─────┬──────────────┐ │ File │ Size │ LastModified │ ├───────────────────────────────┼─────┼──────────────┤ │ catalog.json │ 571 │ 1/9/2026, 6:29:30 PM │ ├───────────────────────────────┼─────┼──────────────┤ │ sync-output/products-20220209T222727.csv │ 3226419 │ 1/9/2026, 5:27:34 PM │ └───────────────────────────────┴─────┴──────────────┘ ℹ Info: Downloading files to `.` ✔ Finished: Downloading file: catalog.json ✔ Finished: Downloading file: sync-output/products-20220209T222727.csv ``` ### Parameters | Option | Default | Description | | - | - | - | | `--include-configs` | `false` | When enabled, also downloads `target-config.json`, `source-config.json`, `tenant-config.json` and sets the `API_KEY` environment variable. | | `--overwrite` | | | | `-o` | `false` | When enabled, overwrites any files that already exist locally in the download to directory. | | `--downloadTo` | | | | `-d` | `.` | The directory to download the job data to. Defaults to the local directory. | ### Running the ETL with the jobs environment variables After running the `setup-local-run` command a `.env` file will be created containing the same environment variables that were available when the job ran in the hotglue environment.\ In order to run the ETL with those same environment variables use one of the following methods: #### For VSCode and it's variants Open the launcher file `{project_folder}/.vscode/launch.json` and add the `envFile` entry for launch configuration: ```json theme={null} { "version": "0.2.0", "configurations": [ ..., { "name": "Run ETL script", "type": "debugpy", "request": "launch", "program": "${workspaceFolder}/etl.py", "console": "integratedTerminal", "cwd": "${workspaceFolder}", "python": "${workspaceFolder}/.venv/bin/python", "envFile": "${workspaceFolder}/.env" } ] } ``` #### For Linux/macOS/Git bash/WSL terminal Run the following: ```shell theme={null} source .env python etl.py ``` # ETL Local Run ### Description Runs the ETL locally replicating the Hotglue environment and compares the `etl-output` files with `etl-output-reference` (the one from the job). The comparator check for extra or missing files in the `etl-output` folder and also compares the matching `.csv` and `.singer` files, if they are not the same an error will be shown. In order to use it you first need to download the Transformation script using the `etl download` command and the job data using the `etl setup-local-run` command. We recommend using this command to reproduce ETL failures or back test again successful jobs. ### Sample where the output matches the output from the job ```shell theme={null} $ hotglue etl local-run ✔ Finished: Building Docker image. With code 0 2026-05-06 13:28:15,194 - ETL Local Run - INFO - Installing dependencies... 2026-05-06 13:28:17,316 - ETL Local Run - INFO - Dependencies installed successfully. 2026-05-06 13:28:17,317 - ETL Local Run - INFO - ######################################################### ################# Running ETL ########################### ######################################################### 2026-05-06 13:28:17,707 - ETL Local Run - INFO - ETL run successfully completed. 2026-05-06 13:28:17,707 - ETL Local Run - INFO - ######################################################### ################# Comparing ETL output ################## ######################################################### 2026-05-06 13:28:17,708 - ETL Local Run - INFO - Comparing file: users.csv 2026-05-06 13:28:17,709 - ETL Local Run - INFO - No differences found in users.csv 2026-05-06 13:28:17,709 - ETL Local Run - INFO - ############################################################## ################ ETL output comparator result ################ ############################################################## 2026-05-06 13:28:17,709 - ETL Local Run - INFO - NOTE: Only files with ('.csv', '.singer') extension are compared. 2026-05-06 13:28:17,709 - ETL Local Run - INFO - Files compared: 2026-05-06 13:28:17,710 - ETL Local Run - INFO - - users.csv 2026-05-06 13:28:17,710 - ETL Local Run - INFO - No differences found in the ETL output! ✔ Finished: Running ETL locally. With code 0 ``` ### Sample where the output doesn't match the output from the job ```shell theme={null} $ hotglue etl local-run ✔ Finished: Building Docker image. With code 0 Docker run failed with code 1. 2026-05-06 14:02:43,905 - ETL Local Run - INFO - Installing dependencies... 2026-05-06 14:02:46,200 - ETL Local Run - INFO - Dependencies installed successfully. 2026-05-06 14:02:46,204 - ETL Local Run - INFO - ######################################################### ################# Running ETL ########################### ######################################################### 2026-05-06 14:02:46,579 - ETL Local Run - INFO - ETL run successfully completed. 2026-05-06 14:02:46,579 - ETL Local Run - INFO - ######################################################### ################# Comparing ETL output ################## ######################################################### 2026-05-06 14:02:46,584 - ETL Local Run - ERROR - Extra files in etl-output: {'customers.csv'} 2026-05-06 14:02:46,584 - ETL Local Run - INFO - Comparing file: users.csv 2026-05-06 14:02:46,585 - ETL Local Run - INFO - No differences found in users.csv 2026-05-06 14:02:46,585 - ETL Local Run - INFO - ############################################################## ################ ETL output comparator result ################ ############################################################## 2026-05-06 14:02:46,585 - ETL Local Run - INFO - NOTE: Only files with ('.csv', '.singer') extension are compared. 2026-05-06 14:02:46,585 - ETL Local Run - INFO - Files compared: 2026-05-06 14:02:46,585 - ETL Local Run - INFO - - users.csv 2026-05-06 14:02:46,585 - ETL Local Run - ERROR - Found differences in the ETL output: Extra files in etl-output: {'customers.csv'} ✖ Error: Running ETL locally. ``` ### Parameters | Option | Default | Description | | - | - | - | | `--etlScriptFolder` | `.` | ETL script folder (downloaded using `etl download`) | | `--jobDataFolder` | `.` | Job data folder (downloaded using `etl setup-local-run`) | | `--dockerPlatform` | ` ` | Docker platform (linux/amd64, linux/arm64, etc.), leave empty to use the default platform of the docker daemon | ### Output comparator options The ETL file comparator has some options that can be set by creating a `test-config.json` file in the Script folder. The options are listed below. #### 1. **`sort_config`** Specifies how rows in a stream and nested fields within rows should be sorted. Supports flat fields, nested fields, and lists of scalars. * **Flat Field Sorting**: Specifies the column used to sort the rows of a stream. * **Nested Field Sorting**: Uses dot notation to sort lists of dictionaries within a row. * **List of Scalars Sorting**: Uses a trailing `.` to sort lists of scalars within a row. **Example Configuration**: ```json theme={null} "sort_config": { "products": [ "id", // Sort rows by "id" "images.id", // Sort "images" (list of dictionaries) by "id" "tags." // Sort "tags" (list of scalars) alphabetically ] } ``` #### 2. **`ignore_columns`** Specifies fields to ignore during the comparison. Supports flat fields and nested fields using dot notation. * **Flat Fields**: Directly removes the specified field from rows. * **Nested Fields**: Removes specified fields within nested structures using dot notation. **Example Configuration**: ```json theme={null} "ignore_columns": { "products": [ "body_html", // Ignore "body_html" column "images.alt" // Ignore "alt" field in "images" (list of dictionaries) ] } ``` #### 3. **`rename_config`** Specifies fields to rename in the etl-output only. Supports flat and nested fields using dot notation. * **Flat Fields**: Renames top-level fields in rows. * **Nested Fields**: Renames fields within nested structures using dot notation. **Example Configuration**: ```json theme={null} "rename_config": { "products": { "created_at": "c_at", // Rename "created_at" to "c_at" "images.created_at": "c_at" // Rename "created_at" to "c_at" within "images" (list of dictionaries) } } ``` # Flows Source: https://docs.hotglue.com/cli/flows hotglue CLI commands for flows Manage flows directly from the CLI. # Flows Create ## Description Creates a new v2 (bidirectional) flow in the hotglue environment. A unique flow ID is generated automatically. ## Sample ```shell theme={null} $ hotglue flows create --env prod.acme.com --name "My Flow" ``` ## Parameters | Option | Default | Description | | - | - | - | | `--env` | | | | `-e` | | Environment ID to create the flow in. | | `--name` | | **Required.** Display name for the flow. | | `--description` | | Optional flow description. | | `--flow-icon` | | Flow icon URL or base64 string. | # Flows List ## Description Lists the flows in the hotglue environment. ## Sample ```shell theme={null} $ hotglue flows list ┌───────────┬────────────────────┬────────┬──────────────────────────┬──────────────────┐ │ ID │ Name │ isPush │ Taps │ Targets │ ├───────────┼────────────────────┼────────┼──────────────────────────┼──────────────────┤ │ RYiRJ3OQM │ Shopify │ false │ [ 'shopify' ] │ [] │ ├───────────┼────────────────────┼────────┼──────────────────────────┼──────────────────┤ │ MDKdfumqM │ Klaviyo │ false │ [ 'klaviyo' ] │ [ 's3' ] │ └───────────┴────────────────────┴────────┴──────────────────────────┴──────────────────┘ ``` ## Parameters | Option | Default | Description | | - | - | - | | `--env` | | | | `-e` | | Environment Id to query flows for. | # Jobs Source: https://docs.hotglue.com/cli/jobs hotglue CLI commands for jobs Programmatically view, clone, and manage jobs using the commands below. # Jobs Download ### Description Clones a remote job to your local machine, under a new directory with the name of the `job_id`. ### Sample ```shell theme={null} $ hotglue jobs download ✔ Finished: Verifying user and authorizing. ✔ Finished: Scanning for downloadable files. ┌─────────────────────────────────────────────────┬─────────┬──────────────────────┐ │ File │ Size │ LastModified │ ├─────────────────────────────────────────────────┼─────────┼──────────────────────┤ │ job-details.json │ 571 │ 2/9/2022, 6:29:30 PM │ ├─────────────────────────────────────────────────┼─────────┼──────────────────────┤ │ sync-output/products-20220209T222727.csv │ 3226419 │ 2/9/2022, 5:27:34 PM │ └─────────────────────────────────────────────────┴─────────┴──────────────────────┘ ✔ Finished: Downloading file: default/flows/bTHIweD0W/jobs/2022/02/2/09/22/KfKW1X/job-details.json. ✔ Finished: Downloading file: default/flows/bTHIweD0W/jobs/2022/02/2/09/22/KfKW1X/sync-output/products-20220209T222727.csv. ``` ### Parameters | Option | Description | | - | - | | `job_root` | The `s3_root` (known as the job root) of the job to clone. Can be found in [Job Details](/key-concepts/jobs/details) or in the URL of the hotglue job page. | > The job root is of the form: `tenant_id/flows/flow_id/jobs/2025/01/1/01/01/job_id` # Jobs List ### Description Lists jobs across the hotglue environment. You can filter the results by tenant, connector, status, and date range. ### Sample ``` $ hotglue jobs list --tenant default --status JOB_COMPLETED --count 5 ✔ Finished: List jobs. ┌────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ name │ details │ ├────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ test:H3XnhScoo │ { │ │ │ "job_id": "KfKW1X", │ │ │ "env_id": "dev.hotglue.acme.com", │ │ │ "flow_id": "bTHIweD0W", │ │ │ "job_name": "test:H3XnhScoo", │ │ │ "tenant": "default", │ │ │ "started_by": "default", │ │ │ "s3_root": "default/flows/bTHIweD0W/jobs/2022/02/2/09/22/KfKW1X", │ │ │ "start_time": "2022-02-09T22:22:19.173879+00:00", │ │ │ "state": {}, │ │ │ "tap": "cin7", │ │ │ "status": "JOB_COMPLETED", │ │ │ "scheduled_job": false, │ │ │ "message": "Status for Job (KfKW1X) was updated to JobStatus.JOB_COMPLETED; (flow: bTHIweD0W) ", │ │ │ "task_id": "864256547fa34584aa61d46eac0d08c5", │ │ │ "last_updated": "2022-02-09T23:29:29.791107+00:00", │ │ │ "processed_rows": 0 │ │ │ } │ ├────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┤ ``` ### Parameters | Option | Default | Description | | - | - | - | | `--count` | `10` | Number of jobs to return, from 1-100. | | `--page` | `1` | Page of results to return. | | `--status` | | Job status to filter on. Supports multiple comma-separated statuses. | | `--tenant` | | | | `-u` | | Tenant ID to filter on. | | `--taps` | | One or more taps to filter on. Multiple taps must be comma-separated. | | `--targets` | | One or more targets to filter on. Multiple targets must be comma-separated. | | `--from` | | Start date for the query, formatted as `YYYY-MM-DD`. | | `--to` | | End date for the query, formatted as `YYYY-MM-DD`. | | `--env` | | | | `-e` | | Environment ID to query jobs for. | # Jobs Status ### Description Polls the status of a job using its job root. ### Sample ```shell theme={null} $ hotglue jobs status --flow bTHIweD0W --tenant default --job-root default/flows/bTHIweD0W/jobs/2025/01/1/01/01/KfKW1X ✔ Finished: Poll job status. { "job_id": "KfKW1X", "env_id": "dev.hotglue.acme.com", "flow": "bTHIweD0W", "tenant": "default", "s3_root": "default/flows/bTHIweD0W/jobs/2025/01/1/01/01/KfKW1X", "status": "JOB_COMPLETED" } ``` ### Parameters | Option | Default | Description | | - | - | - | | `--job-root` | | **Required.** S3 root of the job to poll. | | `--flow` | | | | `-f` | | Flow ID for the job. | | `--tenant` | | | | `-u` | `default` | Tenant ID for the job. | | `--env` | | | | `-e` | | Environment ID for the job. | # Jobs Logs ### Description Gets a page of logs for a job. By default, logs are displayed in a table with timestamp and message columns. Use `--json` to include pagination tokens in the output. ### Sample ```shell theme={null} $ hotglue jobs logs --flow bTHIweD0W --tenant default --job-root default/flows/bTHIweD0W/jobs/2025/01/1/01/01/KfKW1X ✔ Finished: Get job logs. ┌──────────────────────────┬────────────────┐ │ timestamp │ message │ ├──────────────────────────┼────────────────┤ │ 2025-01-01T01:02:03.000Z │ Task completed │ └──────────────────────────┴────────────────┘ ``` ### Parameters | Option | Default | Description | | - | - | - | | `--job-root` | | **Required.** S3 root of the job. | | `--flow` | | | | `-f` | | **Required.** Flow ID for the job. | | `--tenant` | | | | `-u` | `default` | Tenant ID for the job. | | `--env` | | | | `-e` | | Environment ID for the job. | | `--limit` | | Maximum number of log events to return. | | `--next-token` | | Pagination token returned by a previous request. | | `--start-time` | | Earliest event timestamp in epoch milliseconds. | | `--end-time` | | Latest event timestamp in epoch milliseconds. | | `--start-from-head` | `false` | Return the earliest events first. | | `--task-id` | | Get logs for a specific task associated with the job. | For logs, pass `nextForwardToken` back with `--start-from-head` to continue forward, or pass `nextBackwardToken` without it to continue backward. Stop when the API returns the same token again. # Jobs Run ### Description Runs a V1 or V2 job for a tenant. ### Sample ```shell theme={null} $ hotglue jobs run --flow bTHIweD0W --tenant default --tap salesforce --job-name manual-sync ✔ Finished: Run a job. { "job_id": "KfKW1X", "status": "JOB_STARTED", "s3_root": "default/flows/bTHIweD0W/jobs/2025/01/1/01/01/KfKW1X" } ``` To run a V2 job, add `--v2` with `--connector-id` and `--job-type`: ```shell theme={null} $ hotglue jobs run --v2 --flow bTHIweD0W --tenant default --connector-id salesforce --job-type read ✔ Finished: Run a job. { "job_id": "KfKW1X", "status": "JOB_STARTED", "s3_root": "default/flows/bTHIweD0W/jobs/2025/01/1/01/01/KfKW1X" } ``` ### Parameters Options that accept objects should be passed as JSON strings. | Option | Default | Description | | - | - | - | | `--flow` | | | | `-f` | | Flow ID to run the job for. | | `--tenant` | | | | `-u` | `default` | Tenant ID to run the job for. | | `--env` | | | | `-e` | | Environment ID to run the job for. | | `--v2` | `false` | Run a V2 job. Requires `--connector-id` and `--job-type`. | | `--tap` | | Source of the V1 job. | | `--connector-id` | | Connector ID to run for V2 jobs. | | `--job-type` | | V2 job type. Must be `read` or `write`. | | `--job-name` | | Name for the job. | | `--state` | | JSON object with extra context to use in the job. | | `--override-start-date` | | Date to start syncing data from. | | `--override-end-date` | | Date to sync data until. | | `--reset-source-state` | `false` | Run the job as a full sync. | | `--streaming-job` | `false` | Run in streaming mode. | | `--override-selected-tables` | | JSON object with a temporary unified schema object selection. | | `--override-field-map` | | JSON object with a temporary field map. | | `--override-source-config` | | JSON object with a temporary source config override. | | `--override-target-config` | | JSON object with a temporary target config override. | | `--override-connector-config` | | JSON object with a temporary connector config override. | | `--environment-variables` | | JSON object with job environment variable overrides. | # Jobs Bulk Run ### Description Runs multiple jobs in bulk from a JSON file. The command reads a JSON file containing an array of job configurations, validates each job, checks flow versions, and runs all jobs in parallel. Results are displayed in a table format with a summary of successes and failures. ### Sample ```shell theme={null} $ hotglue jobs bulk-run --file ./jobs.json ✔ Finished: Reading jobs file: ./jobs.json. ✔ Finished: Checking flow versions.... ✔ Finished: Running 3 job(s).... ┌───────┬──────────┬─────────┬─────────┬────────────────────────────────────────────────────────────┐ │ Index │ Flow │ Tenant │ Status │ Response/Error │ ├───────┼──────────┼─────────┼─────────┼────────────────────────────────────────────────────────────┤ │ 0 │ bTHIweD0W│ default │ SUCCESS │ { │ │ │ │ │ │ "job_id": "KfKW1X", │ │ │ │ │ │ "status": "JOB_STARTED" │ │ │ │ │ │ } │ ├───────┼──────────┼─────────┼─────────┼────────────────────────────────────────────────────────────┤ │ 1 │ cXYZ1234 │ default │ SUCCESS │ { │ │ │ │ │ │ "job_id": "AbC123", │ │ │ │ │ │ "status": "JOB_STARTED" │ │ │ │ │ │ } │ ├───────┼──────────┼─────────┼─────────┼────────────────────────────────────────────────────────────┤ │ 2 │ dEFG5678 │ tenant1 │ FAILED │ { │ │ │ │ │ │ "statusCode": 404, │ │ │ │ │ │ "statusText": "Not Found", │ │ │ │ │ │ "message": "Flow not found" │ │ │ │ │ │ } │ └───────┴──────────┴─────────┴─────────┴────────────────────────────────────────────────────────────┘ Summary: 2 succeeded, 1 failed out of 3 total. ``` Example JSON file format (`jobs.json`): ```json theme={null} [ { "flow": "bTHIweD0W", "tenant": "tenant1", "tap": "salesforce" }, { "flow": "cXYZ1234", "tenant": "tenant2", "tap": "salesforce", "override_start_date": "2023-11-07T05:31:56Z" }, { "flow": "dEFG5678", "tenant": "tenant3", "tap": "quickbooks", "job_name": "test-job" } ] ``` ### Parameters | Option | Description | | - | - | | `--file` `-f` | **Required.** Path to JSON file containing an array of job objects to run. Each job object must include `flow` and `tenant` fields. Additional job arguments can be included and will be passed to the body of the job trigger endpoint. | # Jobs Bulk Kill ### Description Kills multiple running jobs in bulk. The command fetches jobs from the last month with statuses `JOB_CREATED`, `SYNC_STARTED`, `SYNC_SUCCESS`, `ETL_STARTED`, `ETL_SUCCESS`, or `EXPORT_STARTED`, optionally filters them by tenant IDs and/or flow IDs, and kills all matching jobs in parallel. Results are displayed in a table format with a summary of successes and failures. ### Sample ```shell theme={null} $ hotglue jobs bulk-kill --tenant-ids tenant1,tenant2 --flow-ids bTHIweD0W --reason "Maintenance" ✔ Found 5 job(s) with specified status. ✔ Finished: Killing 5 job(s).... ┌───────┬──────────┬─────────┬──────────────────────────────────────────────────────┬─────────┬────────────────────────────────────────────────────────────┐ │ Index │ Flow │ Tenant │ Job Root │ Status │ Response/Error │ ├───────┼──────────┼─────────┼──────────────────────────────────────────────────────┼─────────┼────────────────────────────────────────────────────────────┤ │ 0 │ bTHIweD0W│ tenant1 │ tenant1/flows/bTHIweD0W/jobs/2025/01/1/01/01/KfKW1X │ SUCCESS │ { │ │ │ │ │ │ │ "status": "JOB_KILLED" │ │ │ │ │ │ │ } │ ├───────┼──────────┼─────────┼──────────────────────────────────────────────────────┼─────────┼────────────────────────────────────────────────────────────┤ │ 1 │ bTHIweD0W│ tenant2 │ tenant2/flows/bTHIweD0W/jobs/2025/01/1/01/02/AbC123 │ SUCCESS │ { │ │ │ │ │ │ │ "status": "JOB_KILLED" │ │ │ │ │ │ │ } │ ├───────┼──────────┼─────────┼──────────────────────────────────────────────────────┼─────────┼────────────────────────────────────────────────────────────┤ │ 2 │ bTHIweD0W│ tenant1 │ tenant1/flows/bTHIweD0W/jobs/2025/01/1/01/03/dEF567 │ FAILED │ { │ │ │ │ │ │ │ "statusCode": 404, │ │ │ │ │ │ │ "statusText": "Not Found", │ │ │ │ │ │ │ "message": "Job not found" │ │ │ │ │ │ │ } │ └───────┴──────────┴─────────┴──────────────────────────────────────────────────────┴─────────┴────────────────────────────────────────────────────────────┘ Summary: 2 succeeded, 1 failed out of 3 total. ``` ### Parameters | Option | Description | | - | - | | `--tenant-ids` `--tenants` | Comma-separated list of tenant IDs to filter jobs by. Only jobs belonging to these tenants will be killed. If not provided, all matching jobs will be considered. | | `--flow-ids` | | | `--flows` | Comma-separated list of flow IDs to filter jobs by. Only jobs for these flows will be killed. If not provided, all matching jobs will be considered. | | `--reason` | Optional reason for killing the jobs. This reason will be included in the kill request for all jobs. | # Jobs Bulk Retrigger ### Description Retriggers multiple jobs in bulk from a JSON file containing job roots. The command reads a JSON file containing an array of job root strings, groups them by tenant and flow, and retriggers jobs with parallel processing across groups and sequential processing within each group. For each group, the command waits for a job to complete before retriggering the next job in that group. Results are displayed in a table format with a summary of successes and failures. ### Sample ```shell theme={null} $ hotglue jobs bulk-retrigger --file ./jobRoots.json ✔ Finished: Reading jobRoots file: ./jobRoots.json. Found 5 jobRoot(s) grouped into 2 tenant/flow group(s). ✔ Finished: Retriggering 5 job(s) across 2 group(s).... ┌─────────┬──────────┬──────────────────────────────────────────────────────┬─────────┬────────────────────────────────────────────────────────────┐ │ Tenant │ Flow │ Job Root │ Status │ Response/Error │ ├─────────┼──────────┼──────────────────────────────────────────────────────┼─────────┼────────────────────────────────────────────────────────────┤ │ tenant1 │ bTHIweD0W│ tenant1/flows/bTHIweD0W/jobs/2025/01/1/01/01/KfKW1X│ SUCCESS │ { │ │ │ │ │ │ "job_id": "KfKW1X", │ │ │ │ │ │ "status": "JOB_STARTED" │ │ │ │ │ │ } │ ├─────────┼──────────┼──────────────────────────────────────────────────────┼─────────┼────────────────────────────────────────────────────────────┤ │ tenant1 │ bTHIweD0W│ tenant1/flows/bTHIweD0W/jobs/2025/01/1/01/02/AbC123 │ SUCCESS │ { │ │ │ │ │ │ "job_id": "AbC123", │ │ │ │ │ │ "status": "JOB_STARTED" │ │ │ │ │ │ } │ ├─────────┼──────────┼──────────────────────────────────────────────────────┼─────────┼────────────────────────────────────────────────────────────┤ │ tenant2 │ cXYZ1234 │ tenant2/flows/cXYZ1234/jobs/2025/01/1/01/03/dEF567 │ FAILED │ { │ │ │ │ │ │ "statusCode": 404, │ │ │ │ │ │ "statusText": "Not Found", │ │ │ │ │ │ "message": "Job not found" │ │ │ │ │ │ } │ └─────────┴──────────┴──────────────────────────────────────────────────────┴─────────┴────────────────────────────────────────────────────────────┘ Summary: 2 succeeded, 1 failed out of 3 total. ``` Example JSON file format (`jobRoots.json`): ```json theme={null} [ "tenant1/flows/bTHIweD0W/jobs/2025/01/1/01/01/KfKW1X", "tenant1/flows/bTHIweD0W/jobs/2025/01/1/01/02/AbC123", "tenant2/flows/cXYZ1234/jobs/2025/01/1/01/03/dEF567" ] ``` ### Parameters | Option | Description | | - | - | | `--file` `-f` | **Required.** Path to JSON file containing an array of job root strings to retrigger. Each job root must follow the format: `{tenantId}/flows/{flowId}/jobs/...`. Jobs are automatically grouped by tenant and flow, and processed sequentially within each group (waiting for completion) while groups are processed in parallel. | # Linked Entities Source: https://docs.hotglue.com/cli/linked-entities Link connectors, sources, and targets to tenants with the hotglue CLI Use the `linked-entities` commands to link connectors, sources, and targets to a tenant on a flow. These are the entities that a tenant has connected for a given flow. Use `supported-entities get` first to discover the connection parameters a connector expects before linking it. # Linked Entities Create ## Description Links an entity to a tenant on a flow. By default, the command links a v2 connector. ## Samples Link a v2 connector: ```shell theme={null} hotglue linked-entities create --env prod.acme.com --flow bTHIweD0W --tenant acme --id shopify ``` Pass the connector configuration as a shell-quoted JSON object: ```shell theme={null} hotglue linked-entities create \ --env prod.acme.com \ --flow bTHIweD0W \ --tenant acme \ --id s3 \ --config '{"bucket":"my-bucket"}' ``` Use `--entity-type` and `--flow-version` to link another entity type: ```shell theme={null} # v2 source hotglue linked-entities create --env prod.acme.com --flow bTHIweD0W --tenant acme --id shopify --entity-type source # v2 target with configuration hotglue linked-entities create --env prod.acme.com --flow bTHIweD0W --tenant acme --id s3 --entity-type target --config '{"bucket":"my-bucket"}' # v1 source hotglue linked-entities create --env prod.acme.com --flow bTHIweD0W --tenant acme --id shopify --entity-type source --flow-version v1 # v1 target hotglue linked-entities create --env prod.acme.com --flow bTHIweD0W --tenant acme --id s3 --entity-type target --flow-version v1 ``` V1 flows support sources and targets, but not connectors. Return machine-readable output for programmatic use: ```shell theme={null} hotglue linked-entities create --env prod.acme.com --flow bTHIweD0W --tenant acme --id s3 --json ``` ## Parameters | Option | Default | Description | | - | - | - | | `--apikey`, `-k` | Profile config | Personal API Key used to authenticate the request. | | `--env`, `-e` | | **Required.** Environment containing the flow. | | `--flow`, `-f` | | **Required.** Flow to link the entity to. | | `--tenant`, `-u` | | **Required.** Tenant to link the entity to. | | `--id` | | **Required.** ID of an available connector, source, or target. | | `--config` | `{}` | Shell-quoted JSON object containing the entity configuration. | | `--entity-type` | `connector` | Entity type. Must be `connector`, `source`, or `target`. | | `--flow-version` | `v2` | Flow version. Must be `v1` or `v2`. | | `--json` | `false` | Return machine-readable output. | # Overview Source: https://docs.hotglue.com/cli/overview A brief overview of the hotglue CLI and installation options ## What is the hotglue CLI? [](https://docs.hotglue.com/docs/cli-overview#what-is-the-hotglue-cli) Rather than manage your hotglue configuration entirely through the UI, hotglue offers a CLI that makes it possible to manage your configuration programmatically. This way, you can check things like your transformation scripts into source control and deploy them via a CI pipeline following best development practices. The CLI also contains several utility functions to make working with hotglue easier. You can list tenants, flows, jobs, and even download jobs locally for debugging and testing. ## Installation You can install the hotglue CLI directly from [npm](https://www.npmjs.com/package/@hotglue/cli). ### Global (recommended) [](https://docs.hotglue.com/docs/cli-overview#global-recommended) We recommend installing the hotglue CLI globally, as shown below: ```shell theme={null} npm install -g @hotglue/cli ``` And then you can run it from anywhere using ```shell theme={null} hotglue --help ``` ### Project Folder [](https://docs.hotglue.com/docs/cli-overview#project-folder) Alternatively, you may install the hotglue CLI locally in a project folder using ```shell theme={null} npm install --save-dev @hotglue/cli ``` And then you can run the local installation from within that folder using ```shell theme={null} npx hotglue ``` # Schedules Source: https://docs.hotglue.com/cli/schedules hotglue CLI commands for flow job schedules Manage a flow's job schedule for a tenant. # Schedules Get ### Description Fetches the current schedule for a tenant and flow. ### Sample ```shell theme={null} hotglue schedules get --tenant tenant123 --flow d2dzyCFnS --json ``` ### Parameters | Option | Default | Description | | - | - | - | | `--tenant` | | Tenant ID | | `--flow` | | Flow ID | | `--env` `-e` | | Environment ID | | `--job-type` | | Job type: `read` or `write` | | `--json` | | Output as JSON | # Schedules Put ### Description Creates or replaces a schedule for a tenant and flow. Defaults `state` to `ENABLED`. ### Sample ```shell theme={null} hotglue schedules put --tenant tenant123 --flow d2dzyCFnS --schedule-expression 'cron(0 5 * * *)' ``` ### Parameters | Option | Default | Description | | - | - | - | | `--tenant` | | Tenant ID | | `--flow` | | Flow ID | | `--schedule-expression` | | Cron expression, e.g. `cron(0 5 * * *)` | | `--env` `-e` | | Environment ID | | `--job-type` | | Job type: `read` or `write` | | `--state` | `ENABLED` | Schedule state: `ENABLED` or `DISABLED` | | `--schedule-jitter-minutes` | | Jitter in minutes (1–720). Only allowed when `--tenant` is `default` | # Schedules Disable ### Description Disables the current schedule for a tenant and flow. ### Sample ```shell theme={null} hotglue schedules disable --tenant tenant123 --flow d2dzyCFnS ``` ### Parameters | Option | Default | Description | | - | - | - | | `--tenant` | | Tenant ID | | `--flow` | | Flow ID | | `--env` `-e` | | Environment ID | | `--job-type` | | Job type: `read` or `write` | # Singer Utils Source: https://docs.hotglue.com/cli/singer hotglue CLI utils for developing Singer tap and targets Develop Singer taps and targets. ## `hotglue singer validate` Validate a Singer file. It ensures that the data conforms to the expected schema and checks for any discrepancies or errors in the data records. ### Sample ```bash theme={null} hotglue singer validate --dataFilePath data.txt 🎉🎉🎉 Singer validation passed 🎉🎉🎉 -------------------------------------- 2 streams validated Record count by stream: contacts: 2500 companies: 513 ``` ### Options * `--dataFilePath`: The path to the data file that needs to be validated. Defaults to **data.singer** * `--allowDuplicateRecords`: A boolean flag to allow duplicate records in the data. Defaults to `false`. The `key_properties` field on SCHEMA messages is used to determine uniqueness for a stream. * `--allowFuzzyTypes`: A boolean flag to allow fields to allow multiple types for a field. Defaults to `false`. * `--json`: Outputs the validation result in JSON format. ## `hotglue singer create-tap` Scaffold a new Singer tap from the [hotglue-tap-cookiecutter](https://github.com/hotgluexyz/hotglue-tap-cookiecutter) template. The generated project uses [HotglueSingerSDK](https://pypi.org/project/hotglue-singer-sdk/). The command uses [cookiecutter](https://cookiecutter.readthedocs.io/). Cookiecutter must be installed and available on your `PATH`: ```bash theme={null} uv tool install cookiecutter ``` If cookiecutter is missing, the command exits with: ``` cookiecutter was not found. Install it with: uv tool install cookiecutter ``` ### Sample #### Interactive: ```bash theme={null} hotglue singer create-tap ``` #### Non-interactive: Pass `-y` or `--yes` to skip cookiecutter prompts and use the flags you provide. Omitted flags fall back to the template defaults. ```bash theme={null} hotglue singer create-tap \ --source-name Stripe \ --admin-name "Hotglue" \ --tap-id tap-stripe \ --library-name tap_stripe \ --stream-type REST \ --stream-names customers,invoices \ --api-base-url https://api.stripe.com \ --auth-method "API Key" \ --include-agent-instructions AGENTS.md \ --license MIT \ --yes ``` #### Options * `-y`, `--yes`: Skip cookiecutter prompts and use the provided flags. Defaults to `false`. * `--source-name`: Source name in CamelCase (for example, `Stripe`). * `--admin-name`: Author full name. * `--tap-id`: Tap ID in kebab-case (for example, `tap-stripe`). * `--library-name`: Python package name in snake\_case (for example, `tap_stripe`). If omitted and `--tap-id` is set, this is derived by replacing hyphens with underscores. * `--stream-type`: Stream type the source provides. One of `REST`, `GraphQL`, `Other`. * `--stream-names`: Comma-separated stream labels (for example, `users,groups`). * `--api-base-url`: API base URL used as `url_base` in `client.py`. * `--auth-method`: Authentication method for REST and GraphQL sources. One of `API Key`, `Bearer Token`, `Basic Auth`, `OAuth2`, `JWT`, `Custom or N/A`. For not interactive mode quote values that contain spaces. * `--include-agent-instructions`: Agent instructions file to include. One of `AGENTS.md`, `CLAUDE.md`, `None`. * `--license`: License for the generated project. One of `MIT`, `Apache-2.0`, `None`. After scaffolding, see [Running taps](/custom-connectors/taps) for local discover, stream selection, and sync. # Snapshots Source: https://docs.hotglue.com/cli/snapshots Download and deploy snapshots for a tenant ## Overview The snapshots commands allow you to deploy and download snapshots across different environments and tenants. ## Commands ### deploy Deploy snapshots to a target environment and tenant. #### Usage ```bash theme={null} hotglue snapshots deploy --sourceFolder ``` #### Options | Option | Type | Required | Default | Description | | - | - | - | - | - | | `--sourceFolder` | string | Yes | - | Path to the source folder containing snapshots to deploy | | `--tenant` | string | Yes | `default` | Target tenant for deployment | #### Examples ```bash theme={null} # Deploy snapshots to default tenant hotglue snapshots deploy --sourceFolder ./snapshots # Deploy snapshots to specific tenant hotglue snapshots deploy --sourceFolder ./snapshots --tenant abc123 ``` *** ### download Download snapshots from a source environment or tenant. #### Usage ```bash theme={null} hotglue snapshots download --downloadTo --overwrite ``` #### Options | Option | Type | Required | Default | Description | | - | - | - | - | - | | `--downloadTo` | string | Yes | - | Destination path where snapshots will be downloaded | | `--overwrite` | boolean | No | - | Whether to overwrite existing files at the destination | | `--tenant` | string | Yes | `default` | Source tenant to download snapshots from | #### Examples ```bash theme={null} # Download snapshots to local directory hotglue snapshots download --downloadTo ./local-snapshots --overwrite true # Download snapshots from specific tenant hotglue snapshots download --downloadTo ./backup --overwrite false --tenant abc1234 ``` # Supported Entities Source: https://docs.hotglue.com/cli/supported-entities Add supported connectors, sources, and targets to flows with the hotglue CLI Use the `supported-entities` commands to manage the connectors that tenants can link to a flow. The entity must already be available in the environment before it can be added to a flow. # Supported Entities Get ## Description Gets a supported entity and returns its connection parameters (`connect_ui_params`). Use this to discover the expected configuration before linking the entity to a tenant. ## Samples Get a v2 connector and its connection parameters: ```shell theme={null} hotglue supported-entities get --env prod.acme.com --flow bTHIweD0W --id shopify ``` Use `--entity-type` and `--flow-version` to get another supported entity type: ```shell theme={null} # v2 source hotglue supported-entities get --env prod.acme.com --flow bTHIweD0W --id shopify --entity-type source # v1 source hotglue supported-entities get --env prod.acme.com --flow bTHIweD0W --id shopify --entity-type source --flow-version v1 ``` Return machine-readable output for programmatic inspection: ```shell theme={null} hotglue supported-entities get --env prod.acme.com --flow bTHIweD0W --id s3 --json ``` ## Parameters | Option | Default | Description | | - | - | - | | `--apikey`, `-k` | Profile config | Personal API Key used to authenticate the request. | | `--env`, `-e` | | **Required.** Environment containing the flow. | | `--flow`, `-f` | | **Required.** Flow to get the supported entity from. | | `--id` | | **Required.** ID of an available connector, source, or target. | | `--entity-type` | `connector` | Entity type. Must be `connector`, `source`, or `target`. | | `--flow-version` | `v2` | Flow version. Must be `v1` or `v2`. | | `--json` | `false` | Return machine-readable output. | # Supported Entities Create ## Description Adds a supported entity to a flow. By default, the command adds a v2 connector. After creation, the command returns the created entity together with its connection parameters (`connect_ui_params`). ## Samples Add a v2 connector: ```shell theme={null} hotglue supported-entities create --env prod.acme.com --flow bTHIweD0W --id shopify ``` Pass connector configuration as a shell-quoted JSON object: ```shell theme={null} hotglue supported-entities create \ --env prod.acme.com \ --flow bTHIweD0W \ --id shopify \ --body '{"client_id":"client-id","client_secret":"client-secret"}' ``` Use `--entity-type` and `--flow-version` to add another supported entity type: ```shell theme={null} # v2 source hotglue supported-entities create --env prod.acme.com --flow bTHIweD0W --id shopify --entity-type source # v2 target with configuration hotglue supported-entities create --env prod.acme.com --flow bTHIweD0W --id s3 --entity-type target --body '{"config":{"bucket":"my-bucket"}}' # v1 source hotglue supported-entities create --env prod.acme.com --flow bTHIweD0W --id shopify --entity-type source --flow-version v1 # v1 target hotglue supported-entities create --env prod.acme.com --flow bTHIweD0W --id s3 --entity-type target --flow-version v1 ``` V1 flows support sources and targets, but not connectors. ## Parameters | Option | Default | Description | | - | - | - | | `--apikey`, `-k` | Profile config | Personal API Key used to authenticate the request. | | `--env`, `-e` | | **Required.** Environment containing the flow. | | `--flow`, `-f` | | **Required.** Flow to add the supported entity to. | | `--id` | | **Required.** ID of an available connector, source, or target. | | `--body` | `{}` | Shell-quoted JSON object containing entity configuration. `--id` takes precedence over an identifier in this object. | | `--entity-type` | `connector` | Entity type. Must be `connector`, `source`, or `target`. | | `--flow-version` | `v2` | Flow version. Must be `v1` or `v2`. | | `--json` | `false` | Return machine-readable output. | # Tenants Source: https://docs.hotglue.com/cli/tenants hotglue CLI commands for tenants View tenants directly from the CLI. # Tenants List ### Description Lists the tenants in the hotglue environment. ### Sample ```shell theme={null} $ hotglue tenants list ``` # Tenants Delete ### Description Deletes a tenant from hotglue (including scheduled jobs and any related jobs history/config files). ### Sample ```shell theme={null} $ hotglue tenants delete -e prod.acme.com -u test-user ✔ Finished: Deleting tenant test-user schedules. ✔ Finished: Verifying user and authorizing. ✔ Finished: Deleting tenant test-user for environment prod.acme.com. ┌─────────────┐ │ Tenant ID │ ├─────────────┤ │ test-user │ └─────────────┘ ``` # Tenants Update Config ### Description Bulk updates the configs of all tenants. This will update the passed JSON into the tenants' configs, not completely overwrite the tenants' configs. ### Sample ```shell theme={null} hotglue tenants update-config ✔ Finished: Retrieving tenants for environment dev.hotglue.testcompany.com. ✔ Finished: Updating config for connector salesforce and flow abc123. ┌─────────────┐ │ Tenant ID │ ├─────────────┤ │ test-user │ └─────────────┘ ``` ### Parameters | Option | Default | Description | | - | - | - | | `--flow` | | The flow to update linked sources/connectors for | | `--connector` | | The connector id to update | | `--configFilePath` | `./config.json` | The relative path to a JSON file containing the desired config updates | # Tenants Custom ETL ### Description Lists all tenants with custom ETL Scripts ### Sample ```shell theme={null} hotglue tenants custom-etl ✔ Finished: Retrieving tenants for environment dev.hotglue.test.com. ✔ Finished: Querying for custom ETL scripts for flow ABC123. ┌─────────────┐ │ Tenant ID │ ├─────────────┤ │ test-user │ └─────────────┘ ``` ### Parameters | Option | Default | Description | | - | - | - | | `--flow` | | The flow to check for forked scripts | | `--connector` | | The connector ID to check for forked scripts | # Tenants Custom Field Map ### Description Lists all tenants with a custom Field Map ### Sample ```shell theme={null} hotglue tenants custom-field-map ✔ Finished: Retrieving tenants for environment dev.hotglue.testcompany.com. ✔ Finished: Querying for custom field maps for flow KeJ5dstJ2. ┌──────────────┬──────────┐ │ Tenant ID │ Connector IDs │ ├──────────────┼──────────┤ │ anonymous-user-5 │ intacct │ └──────────────┴──────────┘ ``` ### Parameters | Option | Default | Description | | - | - | - | | `--flow` | | The flow to check for forked field maps | | `--connector` | | The connector ID to check for forked field maps | # Tenants Custom Catalog ### Description Lists all tenants that have their own catalog for a linked source or connector, instead of the environment's default catalog. Pass `--tenant` to check a single tenant. ### Sample ```shell theme={null} hotglue tenants custom-catalog --flow abc123 ✔ Finished: Retrieving tenants for environment dev.hotglue.test.com. ✔ Finished: Querying for custom catalogs for flow abc123. ┌───────┬────────────┐ │ Tenant ID │ Connector IDs │ ├───────┼────────────┤ │ qb-user │ quickbooks:sandbox │ ├───────┼───────────┤ │ abc31 │ stripe-v2 │ └────────────────────┘ ``` ```shell theme={null} hotglue tenants custom-catalog --flow abc123 --tenant abc31 --json [{"tenant":"abc31","connectors":["stripe-v2"]}] ``` ### Parameters | Option | Default | Description | | - | - | - | | `--flow` | | | | `-f` | | **Required.** The flow to check for forked catalogs | | `--tenant` | | | | `-u` | | Check only this tenant instead of every tenant in the environment | | `--env` | | | | `-e` | | Environment ID | | `--json` | `false` | Print the result as JSON | # Tenants Tenant Config Get ### Description Gets the current tenant config stored in hotglue. ### Sample ```shell theme={null} hotglue tenants tenant-config get --tenant tenant123 ``` ### Parameters | Option | Default | Description | | - | - | - | | `--tenant` | | Tenant ID | | `--env` `-e` | | Environment ID | # Tenants Tenant Config Put ### Description Sets or replaces the tenant config. The payload must be a JSON object. ### Sample ```shell theme={null} hotglue tenants tenant-config put '{"hi":"world","bye":5}' --tenant tenant123 ``` ### Parameters | Option | Default | Description | | - | - | - | | `json` | | JSON object to store as the tenant config | | `--tenant` | | Tenant ID | | `--env` `-e` | | Environment ID | # Tenants Tenant Config Patch ### Description Merges updates into the existing tenant config. The payload must be a JSON object. ### Sample ```shell theme={null} hotglue tenants tenant-config patch '{"hi":"world","byetwo":5}' --tenant tenant123 ``` ### Parameters | Option | Default | Description | | - | - | - | | `json` | | JSON object with fields to merge into the tenant config | | `--tenant` | | Tenant ID | | `--env` `-e` | | Environment ID | # Composite MCP Source: https://docs.hotglue.com/composite-mcp/overview One authenticated MCP endpoint for every connector your tenants link through Hotglue **Composite MCP** is a single authenticated MCP endpoint that exposes tools from the connectors each tenant has linked in Hotglue. Instead of wiring every third-party MCP into your AI client separately, you connect once and get a unified, tenant-scoped tool surface. The live endpoint is: ``` https://composite-mcp.hotglue.com/mcp ``` Composite MCP handles three things for you: 1. **Authentication** — validates a per-tenant bearer token issued by Hotglue 2. **Tool discovery** — surfaces available tools from linked connectors that have an MCP backend 3. **Routing** — proxies tool calls to the underlying MCP (an official provider like Notion or Atlassian, or a custom MCP built by Hotglue) # Why a composite MCP? MCP clients typically need a separate server configuration per provider — each with its own auth flow, token refresh, and tool namespace. That breaks down when you ship integrations to many customers: * Each tenant links different connectors * Credentials live in Hotglue, not in the AI client * You want one MCP URL in Cursor, Claude, or any MCP-compatible agent A **composite MCP server** sits in front of those upstream MCPs. With one connection and one bearer token, your agent sees every tool the tenant is allowed to use — namespaced by connector (for example `notion.search`, `jira.createJiraIssue`). That means you keep using Hotglue's existing connection UX, while AI agents get a single, secure gateway into customer systems. # Demo [Composite MCP Feature Demo](https://www.loom.com/embed/7d4e215368b1494d8b8d2a6192aa9739) # Compatible with existing auth Composite MCP is fully compatible with Hotglue's existing authentication components. Tenants can link connectors the same way they already do today: * **[Embedded widget](/widget-v3/overview)** — users connect integrations in your app * **[Magic Links](/connection-methods/magic-links)** — share a branded URL for connection setup without embedding the widget Once a tenant has linked a supported connector, Composite MCP can discover that link and route tool calls using the credentials stored in Hotglue. You do not need a separate OAuth flow inside the MCP client. # How it works ```mermaid theme={null} sequenceDiagram participant Client as MCP Client participant Composite as Composite MCP participant Hotglue as Hotglue API participant Upstream as Upstream MCP Client->>Composite: POST /mcp (Bearer mcpToken) Composite->>Hotglue: Resolve linked connectors Hotglue-->>Composite: Linked connectors for tenant Composite->>Hotglue: Resolve connector access tokens Hotglue-->>Composite: Access tokens Composite->>Upstream: tools/list Upstream-->>Composite: Provider tools Composite-->>Client: Namespaced tools (e.g. notion.*) Client->>Composite: tools/call notion.search Composite->>Upstream: tools/call search Upstream-->>Composite: Result Composite-->>Client: Proxied result ``` 1. Your backend requests a per-tenant MCP token from the Hotglue API 2. Your MCP client connects to `https://composite-mcp.hotglue.com/mcp` with that token as a Bearer credential 3. Composite MCP looks up the tenant's linked connectors and exposes tools from any that have a registered MCP backend 4. Tool calls are authenticated and forwarded to the upstream MCP, then returned to the client # Get a per-tenant MCP token Authentication is **per tenant**. Call the [`/mcpToken`](/api-reference/mcp/generate-mcp-token) endpoint with your API key to generate a bearer token for a specific environment, flow, and tenant: ```bash theme={null} curl --request GET \ --url 'https://api.hotglue.com/{env_id}/{flow_id}/{tenant}/mcpToken' \ --header 'x-api-key: ' ``` Example response: ```json theme={null} { "token": "" } ``` Use the returned `token` value as the Bearer token when calling Composite MCP. Issue a token for each tenant whose connectors the agent should access — the token scopes discovery and tool calls to that tenant's linked credentials. > [!NOTE] > > The MCP token encodes the environment, flow, tenant, public API key, and a JWT used to call the Hotglue API on the tenant's behalf. Treat it like a secret and store it securely on your backend. # Connect an MCP client Point any Streamable HTTP–compatible MCP client at the Composite MCP URL and pass the tenant token in the `Authorization` header. Example configuration: ```json theme={null} { "mcpServers": { "hotglue": { "url": "https://composite-mcp.hotglue.com/mcp", "headers": { "Authorization": "Bearer " } } } } ``` Replace `` with the `token` returned by `/mcpToken` for the tenant. # Upstream MCP backends Composite MCP routes to upstream MCP servers based on the connectors linked for the tenant. That can include: * **Official provider MCPs** — for example Notion (`https://mcp.notion.com/mcp`) or Atlassian / Jira * **Custom MCPs built by Hotglue** — for connectors where Hotglue maintains the MCP surface Only linked connectors with a known MCP backend are exposed. Tools are namespaced as `{connector}.{tool_name}` so agents can tell providers apart when multiple connectors are linked. # Quick start checklist 1. Let the tenant link connectors via the [widget](/widget-v3/overview) or a [Magic Link](/connection-methods/magic-links) 2. Generate an MCP token with [`GET /{env_id}/{flow_id}/{tenant}/mcpToken`](/api-reference/mcp/generate-mcp-token) 3. Configure your MCP client with `https://composite-mcp.hotglue.com/mcp` and `Authorization: Bearer ` 4. List tools — you should see namespaced tools for each supported linked connector 5. Call tools as usual; Composite MCP authenticates and proxies to the upstream MCP # Changelog Source: https://docs.hotglue.com/connection-methods/embedded-widget/changelog This changelog documents the updates, enhancements, and bug fixes for the `@hotglue/widget` package. **2025-04-04** v1.4.93 ### Fixed * Improved accessibility with tooltips on Connections component. **2025-03-18** v1.4.92 ### Fixed * Improved accessibility with clearer aria labels for Connections component and updating colors to meet minimum contrast ratio thresholds. **2025-02-05** v1.4.91 ### Fixed * Improved accessibility with aria labels for Connections component `link` and `settings` buttons **2025-01-22** v1.4.90 ### Fixed * Added more accessibility improvements across the widget **2025-01-08** v1.4.88 ### Fixed * Improved accessibility with aria labels for sync status, icons, and buttons * Enhanced icon and image components with alt text and aria descriptions ### Added * Added support for connector-level schedules via the toggle in Settings > Widget, `Enable connector schedules`. The scheduling module continues to affect flow-level schedules, as normal, unless this toggle is enabled. **2024-12-18** v1.4.87 ### Fixed * Fixed an issue where `apiUrl` was required in the types **2024-12-17** v1.4.86 ### Fixed * HG-3639: Fixed linked state misalignment for targets in the target flow modal. ### Added * HG-3641: Users are now redirected directly to select `options` after OAuth, when `options` are defined in an availableSource. This is currently only relevant for Xero (tenant selection) and Amazon Advertising (profile selection) integrations. **2024-12-11** v1.4.85 ### Added * Added support for OAuth in tap-faire **2024-12-05** v1.4.84 ### Added * HGI-6913: Added a copyable external ID in the S3 connector settings when using [Cross-account assumeRole authentication](https://docs.hotglue.com/connectors/s3#method-2-cross-account-assumerole-with-external-id) **2024-11-21** v1.4.83 ### Added * Added support for OAuth in tap-amazon-advertising **2024-11-07** v1.4.82 ### Fixed * HG-3567: Fixed missing loading state on job history tab of widget **2024-11-05** v1.4.81 ### Fixed * HG-3555: Fixed empty state misalignment on job history tab of widget **2024-10-21** v1.4.80 ### Fixed * HG-3506: Resolved React warning about missing key prop on job history tab. **2024-10-09** v1.4.79 ### Added * HG-3491: Introduced new `runJob` helper function which introduces support for running v2 flows and specifying the `jobType`, the signature is: ```javascript theme={null} runJob: ( entityId: string, flow: string, tenant: string, startDate: string, jobType: 'read' | 'write', ) => Promise; ``` ### Fixed * HG-3496: Resolved bug where `onConnectorLinked` listener was not triggering when the widget was closed after making an OAuth connection ### Deprecated * HG-3491: As part of introducing the `runJob` helper function we have deprecated `createJob` as it doesn't support v2 flows. **2024-10-08** v1.4.78 ### Fixed * HG-3398: Avoid undefined error when updating `isSelected` value in the field map component **2024-09-16** v1.4.77 ### Fixed * HG-3443: ensure `onLinkFailed` listeners still fire when invalid `connectValues` are passed to `HotGlue.link` function **2024-09-06** v1.4.76 ### Fixed * HG-3422: fixed bug where symlink screen would persist even after successfully linking a connector # Javascript Reference Source: https://docs.hotglue.com/connection-methods/embedded-widget/javascript Using the hotglue widget with plain JavaScript This page is a reference of all the functions accessible from the `HotGlue` object exposed by the `widgetv2.js` script. After [installing the widget](https://docs.hotglue.com/docs/embed-hotglue#installation-vanilla-javascript) using plain JavaScript, you can reference the `HotGlue` (or `window.HotGlue`) object and all the utility functions included in the widget. # open ## Usage `HotGlue.open(user id, options)` ## Parameters | Name | Type | Description | | - | - | - | | user id | `string` | ID of current user of your application. | | options | `objects` | option objects | ## Description Launches the hotglue widget for user with specified options. *** # close ## Usage `HotGlue.close()` ## Description Closes the hotglue widget. *** # preload ## Usage `HotGlue.preload(user id, flow id)` ## Parameters | Name | Type | Description | | - | - | - | | user id | `string` | ID of current user of your application. | | flow id | `string` | ID of flow you wish to connect. Every flow in hotglue has an ID which can be found from the admin panel or API. | ## Description Preloads the relevant user/flow data for usage with the HotGlue.link function. *** # link ## Usage `HotGlue.link(user id, flow id, source, preloaded, options)` ## Parameters | Name | Type | Description | | - | - | - | | user id | `string` | ID of current user of your application. | | flow id | `string` | ID of flow you wish to connect. Every flow in hotglue has an ID which can be found from the admin panel or API. source | | source | `string` | ID of source you wish to connect – typically just the name of the source in lowercase. Full catalog is accessible via API. Ex. `salesforce` | | preloaded | `boolean` | Mark this flag as `true` if you used the `HotGlue.preload` function to improve load time. Defaults to `false` | | options | `object` | Object containing options to configure the form: `json { "helperText": "Need help finding credentials? [Read the docs](https://docs.hotglue.xyz)" }` | ## Description If specified `source` is **not linked**, this will open a popup window for user to login If specified `source` is **linked**, this will open the hotglue widget under specified flow so user can manage the source. *** # reconnect ## Usage `HotGlue.reconnect(user id, flow id, entity id, options)` ## Parameters | Name | Type | Description | | - | - | - | | user id | `string` | ID of current user of your application. | | flow id | `string` | ID of flow you wish to reconnect. Every flow in hotglue has an ID which can be found from the admin panel or API. source | | entity id | `string` | ID of source or target you wish to connect – typically just the name of the source in lowercase. Full catalog is accessible via API. Ex. `salesforce` | | options | `object` | Object containing options to configure the form: `json { "isTarget": false }` | ## Description Used to reconnect an OAuth entities. Note for non-OAuth sources or targets, this will have no effect. In order to reconnect a target, you must pass the `isTarget` parameter to the `options` object. *** # disconnect ## Usage `HotGlue.disconnect(user id, flow id, entity id, options)` ## Parameters | Name | Type | Description | | - | - | - | | user id | `string` | ID of current user of your application. | | flow id | `string` | ID of flow you wish to disconnect. Every flow in hotglue has an ID which can be found from the admin panel or API source | | entity id | `string` | ID of source or target you wish to disconnect – typically just the name of the source in lowercase. Full catalog is accessible via API. Ex. `salesforce` | | options | `object` | Object containing options to configure the form: `json { "isTarget": false }` | ## Description Used to disconnect an entity (source or target). Note you must pass the `isTarget` parameter to the `options` object if disconnecting a linked target. *** # setListener ## Usage `HotGlue.setListener(listener)` ## Parameters | Name | Type | Description | | - | - | - | | listener | `object` | Object containing all listeners. See list of available events below. | | ex. | | | | `{onSourceLinked: (source, flow) => console.log(JSON.stringify(source))}` | | | ## Description Updates current listener configuration to specified listener object *** # getLinkedSources ## Usage `HotGlue.getLinkedSources(flow id, user id)` ## Parameters | Name | Type | Description | | - | - | - | | flow id | `string` | ID of flow to query | | user id | `string` | ID of user to query | ## Response [](https://docs.hotglue.com/docs/embed-hotglue-javascript-reference#response) > [!WARNING] > > Returns a Promise which must be awaited or assigned a callback to extract relevant data ```json JSON theme={null} [{ "tap": "salesforce", "domain": "salesforce.com", "label": "Salesforce", "icon": "https://s3.amazonaws.com/other.hotglue.xyz/images/salesforce.svg", "tap_url": "https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=...", "auth_url": "https://login.salesforce.com/services/oauth2/token", "type": "oauth", "description": "Enable your customers to sync CRM data (Leads, Sales, etc.) directly from Salesforce using hotglue.", "client_id": "...", "fieldMap": {} }] ``` ## Description Convenience function wrapping the hotglue API to check if user has linked sources. *** # createJob ## Usage `HotGlue.createJob(flowId, tenantId, startDate)` ## Parameters | Name | Type | Required | Description | | - | - | - | - | | `flowId` | `string` | Yes | ID of flow | | `tenantId` | `string` | Yes | ID of user | | `startDate` | `string` (ISO date) | No | Optional. Used to override start date of the job. ex: `2022-10-16T00:00:00Z` | ## Response > [!WARNING] > > Returns a Promise which must be awaited or assigned a callback to extract relevant data ```json JSON theme={null} { "job_id": "lmaEbA", "env_id": "dev.example-env.hotglue.xyz", "job_name": "test_job:_V-vgdlLN", "tenant": "default", "started_by": "default", "flow": "l8odS2mce", "s3_root": "default/flows/l8odS2mce/jobs/lmaEbA", "start_time": "2020-12-30T18:01:01.828266+00:00", "state": {}, "tap": "quickbooks:sandbox", "status": "ETL_FAILED", "message": "ETL error...", "last_updated": "2020-12-30T20:31:00.081282+00:00" }` ``` ## Description Convenience function wrapping the hotglue API to run a job for the user. *** # hasMounted ## Usage `HotGlue.hasMounted()` ## Description Returns `true` if the widget has mounted and is ready for use. `false` otherwise. *** ## localization Object specifying localization overrides for text in the widget. ```json JSON theme={null} { "startingScreen": { "header": "Add a Title Here", "subtitle": "Put some caption here" }, "connectSourceScreen": { "instructionText": "Link your account below", "connectDataButtonText": "Link my account now", "saveConfigurationButtonText": "Save my configuration" }, "copySourceScreen": { "header": "Duplicate the same setup from this flow?", "actionButton": "No, I'll use a different account" }, "quickActions": { "runJobsTitle": "Run Jobs", "runJobsSubtitle": "Some instructions for your users to run jobs", "editFieldMapTitle": "Field Map Editor", "editFieldMapSubtitle": "Some instructions for your users to edit Field Map", "reconnectTitle": "Reconnect Source", "reconnectSubtitle": "Some instructions for your users to reconnect the source", "editScheduleTitle": "Edit Time of Sync", "editScheduleSubtitle": "Some instructions for your users to edit sync schedule", "unlinkTitle": "Unlink Source", "unlinkSubtitle": "Some instructions for your users to unlink the source" }, "jobHistory": { "noJobsCaption": "Add text to guide user/s to run jobs!" }, "searchSource": { "searchSourceText": "Search App", "noSourceCaption": "Add text if there is no source upon search", "noSourceAvailableCaption": "There are no source for this flow, try add on the dashboard" }, "searchTarget": { "searchTargetText": "Search Target App", "noTargetCaption": "Add text if there is no target upon search", "noTargetAvailableCaption": "There are no target for this flow, try add on the dashboard" } } ``` # Allow multiple sources Source: https://docs.hotglue.com/connection-methods/embedded-widget/options/allow-multiple-sources Allows tenants to connect to multiple distinct connectors in the same flow By default, users are limited to one linked connector per flow. This is because most users need just one integration for each category of connector you use (e.g. 1 CRM, 1 accounting system). `multipleSources` ignores these limits and allows users to link multiple connectors in the same flow (e.g. Hubspot and Salesforce). ## Syntax ```javascript javascript theme={null} multipleSources: true ``` # Create metadata Source: https://docs.hotglue.com/connection-methods/embedded-widget/options/create-metadata Define tenant metadata like name, industry, or contact `tenantMetadata` allows you to define additional data about your tenant, such as the company name. This will not be visible to your user. It is only accessible via the hotglue dashboard and API. ## Syntax ```javascript javascript theme={null} tenantMetadata: { "Name": "Molot Industries", "Contact": "David Molot" } ``` # Custom Credential Validation Source: https://docs.hotglue.com/connection-methods/embedded-widget/options/custom-credential-validation Specify custom validation logic for credential input in the widget. The `credentialsFormValidator` option allows developers to inject a custom asynchronous validation callback into the widget. This callback will be called when the tenant submits their credentials in the widget. If the custom validator returns an `errorMessage`, it will be displayed to the tenant. ## Syntax ```typescript theme={null} credentialsFormValidator?: ( oldConfig: TConfig, newConfig: TConfig, availableEntity: Record, flowId: string, tenantId: string ) => Promise<{ errorMessage?: string; success: boolean }>; ``` ## Parameters * `oldConfig`: The current configuration settings before the tenant's update. * `newConfig`: The updated configuration settings after the tenant's modification. * `availableEntity`: The availableSource, availableTarget, or availableConnector that they are attempting linking ot * `flowId` * `tenantId` ## Example Usage Below is a simple example demonstrating how to implement the `credentialsFormValidator`: ```typescript theme={null} const myValidator = async ( oldConfig, newConfig, availableEntity, flowId, tenantId ) => { if(newConfig.api_version >= 25) { return { success: false, errorMessage: "Invalid API version specified" } } return { success: true }; }; hotglue.open( "tenant-id", { credentialsFormValidator: myValidator } ) ``` This example checks if a specific field has changed and returns an error message if so, ensuring tenants are informed of exact validation issues in the widget. # Custom field mapping Source: https://docs.hotglue.com/connection-methods/embedded-widget/options/custom-field-mapping Allow users to map their fields to your schema # Behavior Custom field mapping allows your users to map fields in their connected system to your data model. Your users will see your app's schema on the left, and available fields in their source system on the right. ![](https://files.readme.io/c76c847-Screen_Shot_2023-04-09_at_8.04.47_PM.png) # Uses * Fetch available custom fields in your customer's external system without creating new custom fields in your app. * Define schemas tenant-by-tenant for granular control over mapping. > [!NOTE] > > If you need to fetch custom fields, hotglue will first need to fetch available fields in your user's account (a "discover"). There are two ways to do this, both of which can be turned on in your jobs settings: > > * Trigger a discover when your user links. > * Force a discover on every job # Syntax Pass the `schemas` object as an option to the hotglue widget. There are three parameters in this object: * **FlowId**: The shortcode for your flow * **schema.table**: The name of the table inside your system. This can be any string. * **Your data model's field `id`** and `name`: The `id` is the field name in your data model, as a string. The `name` is a user-friendly string that is familiar to your users. Javascript ```javascript javascript theme={null} { "schemas": [ { "flowId": "flowId", "schema": [ { "table": "Leads", "fields": [ { "id": "interest", "name": "Interest Level" }, { "id": "cat", "name": "Test Company category" } ] } ] } } ``` ## One to One Mapping To enforce a one-to-oe relationship between source and target tables you can use the `enforceOneToOneMapping` prop. In the vanilla widget you can pass: ```javascript javascript theme={null} { "enforceOneToOneMapping": true, // default false "schemas": [{...}] } ``` In the React widget you can pass: ```jsx React theme={null} const { setSchema } = useHotglue() const schemas = { "flowId": "flowId", "schema": [{...}] } setSchema(schemas, { enforceOneToOneMapping: true }) ``` Here's how it looks on the widget popup when the flag is passed ![](https://mintcdn.com/hotglue/kt6t7Oo-bSKsLKhl/images/oneToOneMapping.png?fit=max\&auto=format\&n=kt6t7Oo-bSKsLKhl\&q=85\&s=a766836808ccc057caeca1461fc2cb13) # Filter Source: https://docs.hotglue.com/connection-methods/embedded-widget/options/filter Object specifying filters `flowFilter` ## Syntax ```javascript javascript theme={null} flowFilter: (flow) => return flow.name === "Sales" ``` # Hide back buttons Source: https://docs.hotglue.com/connection-methods/embedded-widget/options/hide-back-buttons Hides back buttons in widget. Usually used for the `link` function This is most commonly used with the `link` function to prevent users from moving backward to the flow page. ## Syntax ```javascript javascript theme={null} hideBackButtons: true ``` # Listeners Source: https://docs.hotglue.com/connection-methods/embedded-widget/options/listener Use callbacks to respond to Widget events The `listener` option can be passed in order to respond to various widget events. ## Syntax ```javascript javascript theme={null} listener: { onSourceLinked: (source, flow) => console.log(JSON.stringify(source)) } ``` ## Supported listeners ### onWidgetOpen Signature `()` ### onWidgetClose Signature `()` ### onReconnect Signature `(entityId, flow)` | Name | Type | Description | | - | - | - | | entityId | `string` | ID of the entity (source/target/connector) being reconnected | | flow | `string` | ID of the flow | ### onPopupClose Signature `(id, flowId)` | Name | Type | Description | | - | - | - | | id | `string` | ID of source/target being linked | | flowId | `string` | ID of flow being linked | ### onSourceLinked Signature `(source, flowId, tenantId)` | Name | Type | Description | | - | - | - | | source | `object` | The source that has been linked. Follows same response structure as ​linked sources API | | flowId | `string` | ID of flow that has been linked | | tenantId | `string` | ID of the tenant | ### onTargetLinked Signature `(target, flowId)` | Name | Type | Description | | - | - | - | | target | `object` | The target that has been linked. Follows same response structure as linked targets API | | flowId | `string` | ID of flow that has been linked | ### onConnectorLinked Signature `(connector, flowId, tenantId)` | Name | Type | Description | | - | - | - | | connector | `object` | The connector that has been linked | | flowId | `string` | ID of flow that has been linked | | tenantId | `string` | ID of the tenant | ### onSourceLinkCanceled Signature `(tapId, flowId)` | Name | Type | Description | | - | - | - | | tapId | `string` | ID of source | | flowId | `string` | ID of flow | ### onConnectorLinkCanceled Signature `(connectorId, flowId)` | Name | Type | Description | | - | - | - | | connectorId | `string` | ID of connector | | flowId | `string` | ID of flow | ### onSourceUnlinked Signature `(source, flowId)` | Name | Type | Description | | - | - | - | | source | `string` | The source that has been unlinked | | flowId | `string` | ID of flow that has been unlinked | ### onConnectorUnlinked Signature `(connector, flowId)` | Name | Type | Description | | - | - | - | | connector | `string` | The connector that has been unlinked | | flowId | `string` | ID of flow that has been unlinked | ### onTargetUnlinked Signature `(target, flowId)` | Name | Type | Description | | - | - | - | | target | `string` | The target that has been unlinked | | flowId | `string` | ID of flow that has been unlinked | ### onTargetLinkCanceled Signature `(targetId, flowId)` | Name | Type | Description | | - | - | - | | targetId | `string` | ID of target | | flowId | `string` | ID of flow | ### onSourceLinkFailed Signature `(source, flowId, tenant, errorMessage)` | Name | Type | Description | | - | - | - | | source | `string \| object` | The source that failed to link | | flowId | `string` | ID of flow | | tenant | `string` | ID of the tenant | | errorMessage | `string` | Error message describing the failure | ### onConnectorLinkFailed Signature `(connector, flowId, tenant, errorMessage)` | Name | Type | Description | | - | - | - | | connector | `string \| object` | The connector that failed to link | | flowId | `string` | ID of flow | | tenant | `string` | ID of the tenant | | errorMessage | `string` | Error message describing the failure | ### onTargetLinkFailed Signature `(target, flowId, tenant, errorMessage)` | Name | Type | Description | | - | - | - | | target | `string \| object` | The target that failed to link | | flowId | `string` | ID of flow | | tenant | `string` | ID of the tenant | | errorMessage | `string` | Error message describing the failure | ### onStartJob Signature `(tap_id, flow_id, user_id)` | Name | Type | Description | | - | - | - | | tap\_id | `string` | ID of source the job is running for | | flow\_id | `string` | ID of flow source is linked under | | user\_id | `string` | ID of the tenant who started job | ### onFieldMapSave Signature `(entityId, flowId, tenantId)` | Name | Type | Description | | - | - | - | | entityId | `string` | ID of the entity | | flowId | `string` | ID of the flow | | tenantId | `string` | ID of the tenant | ### onCustomMappingSave Signature `(entityId, flowId, tenantId)` | Name | Type | Description | | - | - | - | | entityId | `string` | ID of the entity | | flowId | `string` | ID of the flow | | tenantId | `string` | ID of the tenant | ### onScheduleSave Signature `(oldSchedule, newSchedule, entityId, flowId, tenantId)` | Name | Type | Description | | - | - | - | | oldSchedule | `object \| null` | The previous schedule configuration before the save. May be `null` if no schedule existed. | | newSchedule | `object \| null` | The newly saved schedule configuration. May be `null` if schedule is cleared. | | entityId | `string \| null` | ID of the entity (source / target / connector) the schedule applies to. May be `null` if using flow schedules. | | flowId | `string` | ID of the flow | | tenantId | `string` | ID of the tenant | # Localization Source: https://docs.hotglue.com/connection-methods/embedded-widget/options/override-default-text `localization` overrides default headers, captions, and buttons in the widget Define custom or branded text inside the widget. ## Syntax ```javascript Javascript theme={null} localization: { "startingScreen": { "header": "Add a Title Here", "subtitle": "Put some caption here" }, "connectSourceScreen": { "instructionText": "Link your account below", "connectDataButtonText": "Link my account now", "saveConfigurationButtonText": "Save my configuration" }, "copySourceScreen": { "header": "Duplicate the same setup from this flow?", "actionButton": "No, I'll use a different account" }, "quickActions": { "runJobsTitle": "Run Jobs", "runJobsSubtitle": "Some instructions for your users to run jobs", "editFieldMapTitle": "Field Map Editor", "editFieldMapSubtitle": "Some instructions for your users to edit Field Map", "reconnectTitle": "Reconnect Source", "reconnectSubtitle": "Some instructions for your users to reconnect the source", "editScheduleTitle": "Edit Time of Sync", "editScheduleSubtitle": "Some instructions for your users to edit sync schedule", "unlinkTitle": "Unlink Source", "unlinkSubtitle": "Some instructions for your users to unlink the source" }, "jobHistory": { "noJobsCaption": "Add text to guide user/s to run jobs!" }, "searchSource": { "searchSourceText": "Search App", "noSourceCaption": "Add text if there is no source upon search", "noSourceAvailableCaption": "There are no source for this flow, try add on the dashboard" }, "searchTarget": { "searchTargetText": "Search Target App", "noTargetCaption": "Add text if there is no target upon search", "noTargetAvailableCaption": "There are no target for this flow, try add on the dashboard" }, "connectorManagementTabs": { "quickActions": "Quick Actions", "credentials": "Credentials", "jobHistory": "Job History", "mapping": "Field Mapping", "triggers": "Triggers", "uploadFiles": "Upload Files" } } ``` # Skip to flow Source: https://docs.hotglue.com/connection-methods/embedded-widget/options/skip-to-flow Instead of showing a list of flows, `flow` will open to a specific flow This can be used with an `open` function to send tenants directly to a specific flow. ## Syntax ```javascript javascript theme={null} flow: "h8Dksj2" ``` # Overview Source: https://docs.hotglue.com/connection-methods/embedded-widget/overview The hotglue widget allows you to offer native, inline integrations in your app with a few lines of code. # Introduction to the widget The hotglue widget is a white-labeled component that allows your users to integrate instantly, without leaving your app. You can embed the widget using a few lines of [Javascript](https://docs.hotglue.com/docs/embed-hotglue) or [React](https://docs.hotglue.com/docs/embed-hotglue). ![](https://files.readme.io/fea0655-Screen_Shot_2023-03-17_at_11.28.28_PM.png) The pop-up widget can be opened with Vanilla Javascript, React, or Next.js ![](https://files.readme.io/be6fcf0-Screen_Shot_2023-03-17_at_11.22.37_PM.png) The inline Connections Component can be used via React or Next.js *** # Installation (React) ## Install the @hotglue/widget package If your project is built in React, you can install the [@hotglue/widget](https://www.npmjs.com/package/@hotglue/widget) package. using npm ``` npm install @hotglue/widget ``` or using yarn ``` yarn add @hotglue/widget ``` ## Launch the widget First you must include the `HotglueConfig` provider as a higher order component in your React app. For example, in `index.js`: ```javascript index.js theme={null} import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import HotglueConfig from '@hotglue/widget'; ReactDOM.render( , document.getElementById('root') ); ``` Now you can launch the widget using the `useHotglue` hook: ```javascript App.js theme={null} import { useHotglue } from '@hotglue/widget'; const App = (props) => { const { openWidget } = useHotglue(); return
} export default App; ``` You can also use the [Connections component](https://docs.hotglue.com/docs/connections) if you want to use the widget inline rather than in a modal. # Installation (Next.js) Just like above, begin by installing the [@hotglue/widget](https://www.npmjs.com/package/@hotglue/widget) package using npm ``` npm install --save @hotglue/widget ``` or yarn ``` yarn add @hotglue/widget ``` Import `HotglueConfig` on your page and configure it. ```javascript next.js theme={null} import dynamic from 'next/dynamic' const HotglueConfig = dynamic(() => import('@hotglue/widget'), { ssr: false }) export default function Home() { return (
)} ``` Create the `HomeComponent`. Inside of it you can launch the widget using the useHotglue hook: ```javascript next.js theme={null} import { useHotglue } from '@hotglue/widget' const HomeComponent = (props, ref) => { const { openWidget } = useHotglue() const handleOpenWidget = (tenant) => { openWidget(tenant) } return (
) } export default HomeComponent ``` You can also use the `connections` component. ```javascript next.js theme={null} import dynamic from 'next/dynamic' const HotglueConfig = dynamic(() => import('@hotglue/widget'), { ssr: false }) import { Connections } from '@hotglue/widget' export default function Home() { return (
) } ``` # Installation (Vanilla JavaScript) [](https://docs.hotglue.com/docs/embed-hotglue#installation-vanilla-javascript) ## 1. Call and mount the widget [](https://docs.hotglue.com/docs/embed-hotglue#1-call-and-mount-the-widget) The first step of embedding hotglue is to add the widget to your web app. Simply copy the code generated from the hotglue environment dashboard into your HTML `head` tag. > [accordion] Default method > > ```javascript HTML theme={null} > > > ``` > [accordion] Async method > > ```javascript HTML theme={null} > > > ``` ## 2. Launch the widget ***Option 1 - HotGlue.link()*** Now that the hotglue widget is installed in your web app, open the widget by calling `HotGlue.link(, , , , )`. In the example below, we also use `options` to hide the back button and add a listener to close the widget once the source is successfully linked. ```HTML theme={null} ``` ***Option 2 - HotGlue.open()*** Alternatively, you can open the widget "flows" menu by calling `HotGlue.open()` ```HTML theme={null} ``` # HotglueConfig Source: https://docs.hotglue.com/connection-methods/embedded-widget/react/hotglue-config HotglueConfig component reference # Description The `HotglueConfig` is a higher order component that must be included in order for the `@hotglue/widget` package to function correctly. # Usage Since the `HotglueConfig` is a provider, it should be included near the entrypoint of your React app. Below is an example of including in the `index.js` of a create-react-app structure. ```javascript index.js theme={null} import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import HotglueConfig from '@hotglue/widget'; ReactDOM.render( , document.getElementById('root') ); ``` # Properties ## config The `config` property is an object which is used to connect to your hotglue environment. The object takes the following parameters: | Name | Description | Required | | - | - | - | | `apiKey` | Your public environment api key | true | | `envId` | Your environment id Usually something like `dev.hotglue.acme.com` | true | | `options` | [An options object](https://docs.hotglue.com/docs/embed-hotglue-javascript-reference#options) | false | ## Implementation notes * The `` component should live at a common ancestor of all the places in your code where you simultaneously use the widget. Multiple copies of the `` component **can not** be mounted simultaneously. # Inline component Source: https://docs.hotglue.com/connection-methods/embedded-widget/react/inline-component Connections React component reference # Description Embeddable React component that allows users to connect and manage their connected integrations. The Connections React component is an inline version of the hotglue widget. Rather than including the widget as a modal (dialog) in your web-app, the Connections component allows for a more native experience. See an example below: ![1246](https://files.readme.io/d7ce86d-qa.hotglue.xyz_env_demo.env.hotglue.xyz_content_home.png "qa.hotglue.xyz_env_demo.env.hotglue.xyz_content_home.png") Connections component preview # Usage First you must include the `HotglueConfig` provider as a higher order component in your React app. For example, in `index.js`: ```javascript index.js theme={null} import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import HotglueConfig from '@hotglue/widget'; ReactDOM.render( , document.getElementById('root') ); ``` Then you can use the `Connections` component, as shown below: ```javascript App.js theme={null} import React from 'react' import { Connections } from '@hotglue/widget'; const App = (props) => { return (
); }; export default App; ``` # Properties | Name | Type | Required | Description | | - | - | - | - | | tenant | `string` | true | ID of current user of your application. | | filterFlow | `function(flowId) => boolean` | false | Function to filter flows. By default renders all flows. `false` to hide, `true` to show. | | filterEntity | `function(flowId, entityId, isTarget) => boolean` | false | Function to filter entities within flows (sources and targets). By default renders all entities. `false` to hide, `true` to show. | | hideFlows | `boolean` | false | If true, will hide the flow container and only render the integrations. | | hideBackButtons | `boolean` | false | If true, will hide the back buttons on the connection page. | | multipleSources | `boolean` | false | If true, will allow tenants to link multiple sources to the same flow. | | localization | `object` | false | A [localization object](https://docs.hotglue.com/docs/embed-hotglue-javascript-reference#localization) | # Styling The Connections component has defined CSS classes that can be used to override the component's styling to more closely match your own UI/UX. ## Flow Container Each flow is rendered as a section within the Connections component. The classes are shown in the graphic below: ![1684](https://files.readme.io/7dde1c8-image_8.png) hotglue - Connections Flow Container classes The classes are also defined in the table below: | Class Name | Description | | - | - | | `hg-flows-container` | Container of the entire flow section | | `hg-flow-title` | Title of the flow | | `hg-flow-subtitle` | Subtitle of the flow (description) | | `hg-connectors` | Container for the connectors section of the flow | ## Connector Card Each connector (both sources and targets) are rendered as a card within the Flow Container. The classes are shown in the graphic below: ![1530](https://files.readme.io/68c4b26-image_7.png) hotglue - Connections Connector Card classes The classes are also defined in the table below: | Class Name | Description | | - | - | | `hg-connector-card` | Card containing the connector | | `hg-connector-card-linked` | Connector card for a linked integration | | `hg-connector-name` | Connector name | | `hg-connector-logo` | Connector logo | | `hg-connector-settings` | Connector settings gear | | `hg-connector-linked` | Connector linked label | ## Example [](https://docs.hotglue.com/docs/connections#example) Included below is a stylesheet to give the `Connections` component a dark theme. ```css CSS theme={null} .hg-flows-container { background-color: #120c23; color: #fff; padding: 24px; } .hg-flows-container .hg-flow-title { font-size: 16px; color: #ddd; } .hg-flows-container .hg-flow-subtitle { font-size: 14px; font-weight: 300; color: #aaa; } .hg-flows-container .hg-connector-card { background: #2a233d; border: none; color: #fff; } .hg-connector-card:hover { cursor: pointer; box-shadow: 0px 4px 0px rgb(93 57 222 / 65%) } .hg-connector-card .hg-connector-name { font-size: 14px; } .hg-connector-card .hg-connector-logo { border-radius: 50%; background-color: #fff; } .hg-connector-card .hg-connector-linked { background: #FA5240; } .hg-connector-card .hg-connector-settings { color: #fff; border: 1px solid #777; } ``` The result looks like below: ![1047](https://files.readme.io/6e597b6-localhost_3000_.png "localhost_3000_.png") Sample styling of Connections component # Overview Source: https://docs.hotglue.com/connection-methods/embedded-widget/react/overview Using the hotglue widget with React This section is a reference for all steps involved with using the hotglue widget after [installing the widget](https://docs.hotglue.com/docs/embed-hotglue#installation-react) using the [@hotglue/widget](https://www.npmjs.com/package/@hotglue/widget) package. To start, you will need to utilize the `HotglueConfig` component near the entrypoint of your React app: > [card] [HotglueConfig](hotglue-config) > > `HotglueConfig` is a higher order component that must be included in order for the `@hotglue/widget` package to function correctly. After that, you can utilize `useHotglue` or `Connections` to display the widget in your app: > [card] [useHotglue](use-the-widget) > > The `useHotglue` is the primary way of using the `@hotglue/widget` package outside of the inline `Connections` component. Use this to launch the widget and access utility functions. > [card] [Connections](inline-component) > > The `Connections` React component is an inline version of the widget. Rather than opening a modal in your app, the Connections component allows for a more native experience. # Use the widget Source: https://docs.hotglue.com/connection-methods/embedded-widget/react/use-the-widget useHotglue React hook reference # Description The `useHotglue` is the primary way of using the `@hotglue/widget` package outside of the inline `Connections` component. Use this to launch the widget and access utility functions. ## Usage First you must include the `HotglueConfig` provider as a higher order component in your React app. For example, in `index.js`: ```javascript index.js theme={null} import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import HotglueConfig from '@hotglue/widget'; ReactDOM.render( , document.getElementById('root') ); ``` Then you can use the `useHotglue` hook anywhere, as shown below: ```javascript App.js theme={null} import { Connections } from '@hotglue/widget'; const App = (props) => { const { openWidget } = useHotglue(); return (
); }; export default App; ``` # Functions Below is a reference of all of the currently supported functions from the `useHotglue` hook. *** ## openWidget Opens the widget for a user with options. ### Usage `HotGlue.openWidget(user id, options)` ### Parameters | Name | Type | Description | | - | - | - | | user id | `string` | ID of current user of your application. | | options | `objects` | [option](https://docs.hotglue.com/docs/options) objects | *** ## link ### Usage `HotGlue.link(user id, flow id, source, preloaded, options)` ### Parameters | Name | Type | Description | | - | - | - | | user id | `string` | ID of current user of your application. | | flow id | `string` | ID of flow you wish to connect. Every flow in hotglue has an ID which can be found from the admin panel or API. source | | source | `string` | ID of source you wish to connect – typically just the name of the source in lowercase. Full catalog is accessible via API. Ex. `salesforce` | | preloaded | `boolean` | Mark this flag as `true` if you used the `HotGlue.preload` function to improve load time. Defaults to `false` | | options | `object` | Object containing options to configure the form: `json { "helperText": "Need help finding credentials? [Read the docs](https://docs.hotglue.xyz)" }` | ### Description If specified `source` is **not linked**, this will open a popup window for user to login If specified `source` is **linked**, this will open the hotglue widget under specified flow so user can manage the source. *** ## reconnect ### Usage `HotGlue.reconnect(user id, flow id, entity id, options)` ### Parameters | Name | Type | Description | | - | - | - | | user id | `string` | ID of current user of your application. | | flow id | `string` | ID of flow you wish to reconnect. Every flow in hotglue has an ID which can be found from the admin panel or API. source | | entity id | `string` | ID of source or target you wish to connect – typically just the name of the source in lowercase. Full catalog is accessible via API. Ex. `salesforce` | | options | `object` | Object containing options to configure the form: `json { "isTarget": false }` | ### Description Used to reconnect an OAuth entities. Note for non-OAuth sources or targets, this will have no effect. In order to reconnect a target, you must pass the `isTarget` parameter to the `options` object. *** ## disconnect ### Usage `HotGlue.disconnect(user id, flow id, entity id, options)` ### Parameters | Name | Type | Description | | - | - | - | | user id | `string` | ID of current user of your application. | | flow id | `string` | ID of flow you wish to disconnect. Every flow in hotglue has an ID which can be found from the admin panel or API. | | source | | | | entity id | `string` | ID of source or target you wish to disconnect – typically just the name of the source in lowercase. Full catalog is accessible via API. Ex. `salesforce` | | options | `object` | Object containing options to configure the form: `json { "isTarget": false }` | ### Description Used to disconnect an entity (source or target). Note you must pass the `isTarget` parameter to the `options` object if disconnecting a linked target. *** ## setListener ### Usage `HotGlue.setListener(listener)` ### Parameters | Name | Type | Description | | - | - | - | | listener | `object` | Object containing all listeners. See list of available events [here](/connection-methods/embedded-widget/options/listener). ex. `{onSourceLinked: (source, flow) => console.log(JSON.stringify(source))}` | ## Description Updates current listener configuration to specified listener object *** ## createJob ### Usage `HotGlue.createJob(flowId, tenantId, startDate)` ### Parameters | Name | Type | Required | Description | | - | - | - | - | | `flowId` | `string` | Yes | ID of flow | | `tenantId` | `string` | Yes | ID of user | | `startDate` | `string` (ISO date) | No | Optional. Used to override start date of the job. ex: `2022-10-16T00:00:00Z` | ### Response > [!WARNING] > > Returns a Promise which must be awaited or assigned a callback to extract relevant data ```json JSON theme={null} { "job_id": "lmaEbA", "env_id": "dev.example-env.hotglue.xyz", "job_name": "test_job:_V-vgdlLN", "tenant": "default", "started_by": "default", "flow": "l8odS2mce", "s3_root": "default/flows/l8odS2mce/jobs/lmaEbA", "start_time": "2020-12-30T18:01:01.828266+00:00", "state": {}, "tap": "quickbooks:sandbox", "status": "ETL_FAILED", "message": "ETL error...", "last_updated": "2020-12-30T20:31:00.081282+00:00" } ``` ### Description Convenience function wrapping the hotglue API to run a job for the user. ## close() ### Usage ```js theme={null} const { link, close } = useHotglue() function onClick() { link(tenantId, flowId, sourceId, false, { hideBackButtons: true, listener: { onSourceLinked: () => { close(); } } }) } ``` ### Description Closes the hotglue widget. ## setOptions ### Usage ```js theme={null} const { setOptions } = useHotglue() setOptions({ hideBackButtons: true, listener: { onSourceLinked: (source, flow) => console.log('Source linked!') } }) ``` ### Parameters | Name | Type | Description | | - | - | - | | options | `Options` | Object containing widget configuration options. See [available options](/connection-methods/embedded-widget/options) for complete reference. | ### Description Updates the current widget configuration with new options. This function allows you to widget behavior globally. The options object can contain any of the supported widget configuration parameters. ### Available Options The `options` parameter accepts an object with the following properties: | Option | Type | Description | | - | - | - | | `hideBackButtons` | `boolean` | Hides back buttons in the widget. Useful for preventing users from navigating away from specific flows. | | `listener` | `object` | Object containing event listeners. See [listener options](/connection-methods/embedded-widget/options/listener) for available events. | | `multipleSources` | `boolean` | Allows tenants to connect multiple distinct connectors in the same flow. | | `flow` | `string` | Opens the widget directly to a specific flow instead of showing the flow list. | | `flowFilter` | `function` | Function to filter which flows are displayed. | | `localization` | `object` | Object containing text overrides for widget UI elements. | | `createMetadata` | `object` | Object containing metadata to be created with new connections. | | `customFieldMapping` | `object` | Object containing custom field mapping configuration. | ### Example ```js theme={null} const { setOptions, openWidget } = useHotglue() // Configure widget options setOptions({ hideBackButtons: true, multipleSources: true, flow: "h8Dksj2", listener: { onSourceLinked: (source, flowId, tenantId) => { console.log(`Source ${source.name} linked to flow ${flowId}`) }, onWidgetClose: () => { console.log('Widget closed') } }, localization: { startingScreen: { header: "Connect Your Data", subtitle: "Choose your integration below" } } }) // Open widget with the configured options openWidget('user-123') ``` *** ## setSchema ### Usage ```js theme={null} import { useHotglue } from '@hotglue/widget' const { setSchema, openWidget } = useHotglue() const schemas = [ { flowId: 'flow_123', schema: [ { table: 'Leads', fields: [ { id: 'first_name', name: 'First Name' }, { id: 'last_name', name: 'Last Name' }, { id: 'email', name: 'Email' } ] } ] } ] setSchema(schemas, { enforceOneToOneMapping: true }) openWidget('user-123') ``` ### Parameters | Name | Type | Description | | - | - | - | | `schemas` | `Array` | Array of flow-level schema definitions. Each item includes `flowId` and a `schema` array with `table` and `fields` (`id`, `name`). | | `options` | `SchemaOptions` | Optional behavior overrides for mapping. Currently supports `enforceOneToOneMapping` (`boolean`). | ### Description Enables the custom mapping component and sets the source schema for the widget at runtime when using `@hotglue/widget` in React. Use this to define the fields your users map from before opening the widget. When `enforceOneToOneMapping` is `true`, each source field can only map to one target field, preventing duplicate mappings in the UI. For full schema structure details, see [custom field mapping](/connection-methods/embedded-widget/options/custom-field-mapping). *** # Magic Links Source: https://docs.hotglue.com/connection-methods/magic-links Connect your customers to integrations with powerful links # Overview Magic Links are a streamlined way to connect your customers to integrations using a customizable URL. This eliminates the need to embed hotglue's widget, manage JWTs, or implement custom authentication workflows. Magic Links allow you to: * Generate secure, shareable URLs for integration setup * Customize the appearance to match your brand * Control which flows and connectors users can access * Track and manage user connections [Magic Link Feature Demo](https://www.loom.com/embed/31202df534084ad1803e549e6d734f82?sid=5a5b654f-84f9-47e5-9c35-7daa29e11342) # Quick Start Guide ## 1. Brand your magic link 1. Go to **Settings** > **Widget** 2. Select your brand color and fonts 3. Go to **Settings** > **Magic Link** 4. Add your logo, with a title and description for your page. 5. Add custom helper buttons ## 2. Add a custom domain (Pro Plan) > [!NOTE] > > If you don't see Custom Domain settings, ask the hotglue team to enable it! 1. **Choose Domain:** * Go to **Settings > Magic Link**. * Enter the full subdomain to deploy the magic link to (e.g., `links.example.com`). 2. **Verify Ownership:** * Add the provided CNAME record via your DNS provider. * Make sure you turn off proxying for the CNAME, if it's on by default. 3. **Route Traffic:** * Once the first CNAME is detected, you will get a second CNAME record. * Add the second record to route traffic through our secure servers. It may take up to 10 minutes for your domain to propogate. If you are having trouble, ask the hotglue team! ## 3. Generate a Magic Link via your dashboard 1. Go to **Tenants** > **Create Magic Link** 2. Enter tenant ID (required) 3. To limit tenants to particular flows or connectors, select flows and connectors to display (optional) 4. Click a "Generate Link" 5. Send it to a customer! 🚀 ## 4. Generate a Magic Link via API > [!NOTE] > > To try out your own requests, check out the [API reference for Magic links](/api-reference/manage-tenants/create-magic-link). 1. `POST {env_id}/magicLink` with your **Personal Access Token** or **Secret API Key**, along with a `tenant` ID. ```bash Basic Magic Link theme={null} curl --request POST \ --url https://api.hotglue.com/{env_id}/magicLink \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "tenant": "test-user", "type": "all" }' ``` 2. Optionally, restrict your tenant to a specific flow\... ```bash Flow-locked magic link theme={null} curl --request POST \ --url https://api.hotglue.com/{env_id}/magicLink \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "tenant": "test-user", "flow": "", "type": "flows" }' ``` ... or a specific connector ```bash Connector-locked magic link theme={null} curl --request POST \ --url https://api.hotglue.com/{env_id}/magicLink \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "tenant": "test-user", "flow": "", "entityId": "", "type": "connector" }' ``` 3. Any of the above requests will return a `url` that you can share with customers. ```example Response theme={null} { "url": "https://connect.hotglue.com/?token=XXXXXXXXXXXXXXXXXXXXX" } ``` ## 5. Advanced settings When generating a Magic Link, you can pass additional `options` to customize the integration experience. You can use any `options` control that's available to the React widget: ```typescript theme={null} { "tenant": "test-user", "type": "all", "options": { // Your configuration options here } } ``` ### Commonly used Options * `checkLink` - Never show the configuration popup to your user. Just let the authorize. * [`schemas`](/connection-methods/embedded-widget/options/custom-field-mapping) - Enable custom field mapping * [`tenantMetadata`](/connection-methods/embedded-widget/options/create-metadata) - Add additional metadata about your customers, like company names * [`listener`](/connection-methods/embedded-widget/options/listener) - Take action when users connect * [`localization`](/connection-methods/embedded-widget/options/override-default-text) - Custom text and language settings * [`multipleSources/multipleConnectors`](/connection-methods/embedded-widget/options/allow-multiple-sources) - Allow users to connect multiple integrations * [`hideBackButtons`](/connection-methods/embedded-widget/options/hide-back-buttons) - Remove back navigation buttons * `nextStep` - Define next step in flow ### Example Usage The below Magic Link generation request would create a link that: * Displays a mapping module to the user * Redirects the user to the mapping module after they link ```bash theme={null} curl --request POST \ --url https://api.hotglue.com/{env_id}/magicLink \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "tenant": "test-user", "type": "all", "options": { "nextStep": mapping, "schemas": [ { "flowId": "z_hoiFY_5", "schema": [ { "table": "Leads", "fields": [ { "id": "first_name", "name": "First Name" }, { "id": "email", "name": "Email" } ] } ] } ] } }' ``` For detailed documentation on the documented options, click the links above or visit our [Options Reference](/connection-methods/embedded-widget/options). ## Tips * Decide on a good convention for tenant IDs--it will be harder to change later! Org IDs that you use in other parts of your product will work well. * Use the customizable buttons to link to documentation and your support. Need help? Ask the hotglue team! # Abicart Source: https://docs.hotglue.com/connectors/abicart # Connector Details | Name | Value | | :- | :- | | Platform | [Abicart](https://abicart.se) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-abicart](https://gitlab.com/hotglue/tap-abicart) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Abra Source: https://docs.hotglue.com/connectors/abra # Connector Details | Name | Value | | :- | :- | | Platform | [Abra](https://abra.eu) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-abra](https://gitlab.com/hotglue/tap-abra) | | Tap Metrics | Usage: (low) Success Rate: (high) | # ActiveCampaign Source: https://docs.hotglue.com/connectors/activecampaign # Connector Details | Name | Value | | :- | :- | | Platform | [ActiveCampaign](https://activecampaign.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Triggers | Supported (2 triggers available by default) | | Tap Repo | [https://github.com/hotgluexyz/tap-activecampaign](https://github.com/hotgluexyz/tap-activecampaign) | | Target Repo | [https://github.com/hotgluexyz/target-activecampaign](https://github.com/hotgluexyz/target-activecampaign) | | Tap Metrics | Usage: (low) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the ActiveCampaign connector. The first thing you need to do to access your ActiveCampaign API url and API token is log in to [ActiveCampaign](https://www.activecampaign.com/login). ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MfiDoRMsSC0gWXLVMz_%2F-MfiFShCExERpUxc6R42%2FScreen%20Shot%202021-07-28%20at%201.52.22%20PM.png?alt=media\&token=6a658538-0bce-44bc-8b87-0bd185bc94b4) Once you are logged in, you should go ahead and click on the Settings button in the bottom left side of the page. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MfiFU33pQ9Ri3RwcuAR%2F-MfiFkAO6fiNU9TscoMq%2FScreen%20Shot%202021-07-28%20at%201.56.29%20PM.png?alt=media\&token=1c7a312f-1ef2-47ea-94bc-ca31ddd09800) Next, you should now go ahead and click on the Developer tab within your settings. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MfiFU33pQ9Ri3RwcuAR%2F-MfiFviiCDshgw0StM-e%2FScreen%20Shot%202021-07-28%20at%201.57.09%20PM.png?alt=media\&token=d61e6edf-44be-43ab-97ef-5a1551e7eb9b) On this page, you will be able to find both your ActiveCampaign API url and your API key. Copy these credentials into hotglue. # Azure Active Directory Source: https://docs.hotglue.com/connectors/activedirectory # Connector Details | Name | Value | | :- | :- | | Platform | [Azure Active Directory](https://azure.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-activedirectory](https://github.com/hotgluexyz/tap-activedirectory) | | Tap Metrics | Usage: (high) Success Rate: (medium) | # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.2](https://github.com/hotgluexyz/tap-activedirectory/releases/tag/v0.0.2) | bug fixes | > | [v0.0.1](https://github.com/hotgluexyz/tap-activedirectory/releases/tag/v0.0.1) | | # Google Adwords Source: https://docs.hotglue.com/connectors/adwords # Connector Details | Name | Value | | :- | :- | | Platform | [Google Adwords](https://ads.google.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-adwords](https://github.com/hotgluexyz/tap-adwords) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.12.1 - Use standard client\_id and client\_secret config keys](https://github.com/hotgluexyz/tap-adwords/releases/tag/v1.12.1) | Use `client_id` and `client_secret` instead of `oauth_client_id` to conform with pattern of other taps. | # Affinity Source: https://docs.hotglue.com/connectors/affinity # Connector Details | Name | Value | | :- | :- | | Platform | [Affinity](https://affinity.co) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-affinity](https://gitlab.com/hotglue/tap-affinity) | | Target Repo | [https://gitlab.com/hotglue/target-affinity](https://gitlab.com/hotglue/target-affinity) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Agile CRM Source: https://docs.hotglue.com/connectors/agilecrm # Connector Details | Name | Value | | :- | :- | | Platform | [Agile CRM](https://agilecrm.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-agilecrm](https://gitlab.com/hotglue/tap-agilecrm) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Airbase Source: https://docs.hotglue.com/connectors/airbase # Connector Details | Name | Value | | :- | :- | | Platform | [Airbase](https://airbase.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-airbase](https://github.com/hotgluexyz/tap-airbase) | | Target Repo | [https://github.com/hotgluexyz/target-airbase](https://github.com/hotgluexyz/target-airbase) | | Tap Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Target Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Airtable Source: https://docs.hotglue.com/connectors/airtable # Connector Details | Name | Value | | :- | :- | | Platform | [Airtable](https://airtable.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-airtable](https://github.com/hotgluexyz/tap-airtable) | | Target Repo | [https://github.com/hotgluexyz/target-airtable](https://github.com/hotgluexyz/target-airtable) | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (low) | # Credentials Setup Follow the steps below to get the credentials you need to use the Airtable connector. The first thing you will need to do get your Airtable credentials is make an Airtable account. You can [make a free account (or sign up for a paid account) at this link](https://airtable.com/pricing). If you already have an account, you can [log in at this link](https://airtable.com/login). ## Personal API Key First, we are going to go through how to find your personal API key. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeFyuVBp5zXdEgxZli-%2F-MeGI7wojGmyba6V-C-3%2FScreen%20Shot%202021-07-10%20at%2012.36.56%20PM.png?alt=media\&token=2598d569-9aab-4d29-a612-d0754cb4000d) Once you have logged in to Airtable, you will be shown the home page of the Airtable platform. In the top right corner, there is an icon. Go ahead and click that icon. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeFyuVBp5zXdEgxZli-%2F-MeGIwvFOQcJpJNddfpb%2FScreen%20Shot%202021-07-10%20at%2012.45.35%20PM.png?alt=media\&token=960e4feb-f8e2-40b9-9fa2-56cb8ee5c5b5) Now go ahead and click on the Account tab from the drop down. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeFyuVBp5zXdEgxZli-%2F-MeGMdgXloPSwhIvJaUu%2FScreen%20Shot%202021-07-10%20at%2012.58.02%20PM.png?alt=media\&token=ef0b947f-2caa-4d59-a61b-085479000709) On this page, you can see that you have your own personal API key. You should copy that key into the hotglue admin panel where you should be putting in your credentials for your personal API key. ## Airtable Base ID To get your Airtable Base ID, first make sure that you are logged in to your Airtable account. Once you are, head to the [Airtable Standard API page](https://airtable.com/api). ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeGQYkyt7mdwX4mJT07%2F-MeQs1NBsup0UJmc9-F1%2FScreen%20Shot%202021-07-12%20at%201.55.48%20PM.png?alt=media\&token=bdcdf542-d82f-4148-a457-d1f99127c038) Now go ahead and select which Base you want to connect to - in this case, I am going to select my Demo base. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeGQYkyt7mdwX4mJT07%2F-MeQtGL5e6F83g5xyGbt%2FScreen%20Shot%202021-07-12%20at%202.04.18%20PM.png?alt=media\&token=ba8d843f-5751-41e9-9e5d-31ad00a17c73) You will now be on this page where you are able to get the Airtable Base ID. Copy that ID and paste it in the corresponding spot in hotglue. ## Airtable Table Name Once again, to get your Airtable table name, make sure you are logged in to Airtable. You shoul be on the home screen of Airtable. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeR-ceOhbfwI85vCEQx%2F-MeR-fl2-nOgHg0PfN8P%2FScreen%20Shot%202021-07-12%20at%202.32.50%20PM.png?alt=media\&token=51686fa2-ec3e-46d8-a936-57f4a1649826) From the home page, go ahead and select the same base that you previously got the ID for. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeR-ceOhbfwI85vCEQx%2F-MeR0OdMcLfRlAsYeJ2e%2FScreen%20Shot%202021-07-12%20at%202.38.17%20PM.png?alt=media\&token=0f25f7fa-6e7a-4315-b418-d167c7128922) In the top left corner, you will be able to find the name of the table. If you have multiple tables in one base, make sure you write the name of the table you want your data to end up in. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.3 - Catalog issues resolved](https://github.com/hotgluexyz/tap-airtable/releases/tag/v0.0.3) | Update catalog handling to conform to Singer spec. Metadata property is now correctly created + schema is used properly. | # Target Changelog > [accordion] Target Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.2 – Remove table\_name parameter](https://github.com/hotgluexyz/target-airtable/releases/tag/v0.0.2) | Rather than use a static `table_name` parameter, we will handle an arbitrary # of streams by using the `stream_name` as the `table_name` in Airtable | # Airwallex Source: https://docs.hotglue.com/connectors/airwallex # Connector Details | Name | Value | | :- | :- | | Platform | [Airwallex](https://airwallex.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-airwallex](https://github.com/hotgluexyz/tap-airwallex) | | Target Repo | [https://github.com/hotgluexyz/target-airwallex](https://github.com/hotgluexyz/target-airwallex) | | Tap Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Target Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Altium 365 Source: https://docs.hotglue.com/connectors/altium # Connector Details | Name | Value | | :- | :- | | Platform | [Altium 365](https://altium.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-altium](https://gitlab.com/hotglue/tap-altium) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Amazon Ads Source: https://docs.hotglue.com/connectors/amazon-advertising # Connector Details | Name | Value | | :- | :- | | Platform | [Amazon Ads](https://advertising.amazon.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-amazon-ads](https://gitlab.com/hotglue/tap-amazon-ads) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Amazon Seller Source: https://docs.hotglue.com/connectors/amazon-seller # Connector Details | Name | Value | | :- | :- | | Platform | [Amazon Seller](https://sellercentral.amazon.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-amazon-seller](https://github.com/hotgluexyz/tap-amazon-seller) | | Tap Metrics | Usage: | | Unified Schema | [Supported in Ecommerce Unified Schema.](https://hotglue.com/docs/unified) | # Credentials Setup The Amazon Seller connector utilizes the Selling Partner API to fetch your customers' selling data. 1. To start, you will need to [register as a Public SP-API Developer](https://developer-docs.amazon.com/sp-api/docs/register-as-a-public-developer?ld=NSGoogle\&pageName=US%3ASPDS%3ASPAPI-getting-started-guide). 2. Once you are registered and create your first app, you will receive three credential strings: 1. Your App ID (e.g.`amzn1.sp.solution.<...>` ) 2. Your LWA Client ID (e.g.`amzn1.application-oa2-client.<...>` ) 3. Your LWA Client Secret (e.g. `amzn1.oa2-cs.v1.<...>` ) 3. Once you have your credentials, go to Settings > Connectors. 1. Open `Bi-Directional Connectors` (V2 flows) or `Sources & Targets` (V1 flows) depending on the flow type that you use. 2. If modifying a Connector, add your LWA Client ID to the definition via `options.config.lwa_client_id`. 3. If modifying a Source, add your LWA Client ID to the definition via `config.lwa_client_id`. ![Go to AWS Redshift](https://mintcdn.com/hotglue/ja6ehIwOmiSUju2Z/connectors/images/Amazon_Seller_Connector_Settings.png?fit=max\&auto=format\&n=ja6ehIwOmiSUju2Z\&q=85\&s=31c508cf275b22d0fbcf04ec59a19b46) ![Go to AWS Redshift](https://mintcdn.com/hotglue/ja6ehIwOmiSUju2Z/connectors/images/Amazon_Seller_Source_Settings.png?fit=max\&auto=format\&n=ja6ehIwOmiSUju2Z\&q=85\&s=ec84edfb22fa4a9ec0c55b1d17cc0dad) 5. Finally, go to your flow, add Amazon Seller, and add your `App ID` and `LWA Client Secret` as the Client ID and Client Secret. 6. After clicking save, you will go through authorization of your test shop. This "enables" the Amazon Seller Central connector. After a successful authorization, Amazon Seller is ready to be authorized by your users! # Amazon Vendor Central Source: https://docs.hotglue.com/connectors/amazon-vendor-central # Connector Details | Name | Value | | :- | :- | | Platform | [Amazon Vendor Central](https://vendorcentral.amazon.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-amazon-vendor-central](https://github.com/hotgluexyz/tap-amazon-vendor-central) | | Tap Metrics | Usage: (low) | # Amplitude Source: https://docs.hotglue.com/connectors/amplitude # Connector Details | Name | Value | | :- | :- | | Platform | [Amplitude](https://amplitude.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-amplitude](https://gitlab.com/hotglue/tap-amplitude) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Amplitude connector. # Obtain your Client ID and API Key The first thing you need to do is log in to [Amplitude](https://analytics.amplitude.com/login). ![](https://files.readme.io/5005d4f-amplitude-02.png "amplitude-02.png") The screen will appear where you can enter the organization name and click on Log In button. ![](https://files.readme.io/509fe2e-amplitude-03.png "amplitude-03.png") Now, you should enter the credentials and hit the Log In button. ![](https://files.readme.io/c8541a3-amplitude-04.png "amplitude-04.png") On this page, click on the Settings button. ![](https://files.readme.io/dc4f285-amplitude-05png.png "amplitude-05png.png") Click on Project on the right side breadcrumb. ![](https://files.readme.io/f24385b-amplitude-06.png "amplitude-06.png") Select the project name. Here I am selecting Hotglue. ![](https://files.readme.io/2e55b84-amplitude-07.png "amplitude-07.png") You can get API key on this page. ![](https://files.readme.io/3fac274-amplitude-08.png "amplitude-08.png") Click on the show **button**, you can get the Secret key. Here are the credentials you need to plug into hotglue! # API Source: https://docs.hotglue.com/connectors/api # Connector Details | Name | Value | | :- | :- | | Platform | [API](https://api) | | Auth Type | API Keys | | Direction | Bidirectional | | Target Repo | [https://github.com/hotgluexyz/target-api](https://github.com/hotgluexyz/target-api) | | Tap Metrics | Usage: (high) | | Target Metrics | Usage: (high) | # Overview The API connector lets you move data between your product and HTTP endpoints via hotglue. You can use it as a **target** to send records to an API, or as a **source** to push JSON data into a hotglue write job. ## Writing data to an API endpoint As a target, the API connector sends data to a configured endpoint as JSON `POST` requests. Configure the endpoint URL, authentication, and other settings in your flow, and hotglue will deliver records from write jobs to that destination. The API connector's write behavior is powered by [target-api](https://github.com/hotgluexyz/target-api), a hotglue maintained Singer target. To see all supported settings and capabilities, view the repository's [README](https://github.com/hotgluexyz/target-api). ## Pushing data via the API source As a source, the API connector does not pull data from arbitrary external APIs. Instead, your product pushes data into hotglue, which writes it to the configured target. There are two ways to do this: ### POST /jobs endpoint Send records in the `state` field of a [`POST /jobs`](/key-concepts/jobs/write-jobs#trigger-a-write-job-via-api) request. hotglue starts the write job when you call the endpoint, but the records are exported inside the job—not in the API response itself. You won't receive per-record success or failure in the response; check results in the hotglue dashboard or via the jobs API after the job completes. Use this approach when you need to send **many records at once** or want **universal support across all targets**. See [Trigger a write job via API](/key-concepts/jobs/write-jobs#trigger-a-write-job-via-api) for request examples and v1/v2 flow details. ### Real-time write Send a record to the [real-time write endpoint](/api-reference/real-time/write). hotglue writes the record synchronously and returns success or failure directly in the API response. Use this approach when you need **immediate feedback** on a single record write—for example, confirming a contact was created in a tenant's CRM before showing success in your product. Real-time write is supported for many targets, but not all, which differs compared to the POST /jobs endpoint approach. See the [real-time write API reference](/api-reference/real-time/write) for request format and response details. ## Reading from external APIs The API source does **not** support fetching data from arbitrary third-party APIs. It is designed for pushing data from your product into hotglue, not for extracting data from other systems. If you need to read data from a custom HTTP endpoint, build a custom Singer tap to extract the data. See [Creating Singer taps](/custom-connectors/creating-singer-taps) for instructions on scaffolding a tap with the hotglue cookiecutter template and HotglueSingerSDK. # Target Changelog > [accordion] Target Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.15](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.15) | | > | [v0.0.14](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.14) | | > | [v0.0.13](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.13) | | > | [v0.0.12](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.12) | | > | [v0.0.11](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.11) | | > | [v0.0.10](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.10) | bug fixes | > | [v0.0.9](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.9) | | > | [v0.0.8](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.8) | | > | [v0.0.7](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.7) | | > | [v0.0.6](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.6) | | > | [v0.0.5](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.5) | | > | [v0.0.4](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.4) | | > | [v0.0.3](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.3) | | > | [v0.0.2](https://github.com/hotgluexyz/target-api/releases/tag/v0.0.2) | | # AppsFlyer Source: https://docs.hotglue.com/connectors/appsflyer # Connector Details | Name | Value | | :- | :- | | Platform | [AppsFlyer](https://appsflyer.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/blotoutio/tap-appsflyer](https://github.com/blotoutio/tap-appsflyer) | | Target Repo | [https://github.com/hotgluexyz/target-appsflyer](https://github.com/hotgluexyz/target-appsflyer) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the AppsFlyer connector. # Obtain your AppsFlyer API Key and App ID The first thing you need to do is log in to [AppsFlyer](https://hq1.appsflyer.com/auth/login). They have a free tier, so if you don't have an account, you can make one. ![](https://files.readme.io/f0818ca-Screen_Shot_2022-01-03_at_7.25.24_PM.png "Screen Shot 2022-01-03 at 7.25.24 PM.png") Your home page should look something like this. On the top right side of your screen, you should click the **Add app** button. ![](https://files.readme.io/7516b4f-Screen_Shot_2022-01-03_at_7.28.25_PM.png "Screen Shot 2022-01-03 at 7.28.25 PM.png") ![](https://files.readme.io/46d45c9-Screen_Shot_2022-01-03_at_7.32.58_PM.png "Screen Shot 2022-01-03 at 7.32.58 PM.png") You should now be asked a few questions about how you would like your app configured. I am going to select the Mobile option, the iOS option, and create an **App ID**. Make sure to copy this down as this is one of the credentials you need to put into hotglue! ![](https://files.readme.io/45e6341-Screen_Shot_2022-01-03_at_7.37.06_PM.png "Screen Shot 2022-01-03 at 7.37.06 PM.png") Now that you are done configuring your app, go ahead and select **Add my app**. ![](https://files.readme.io/6897a17-Screen_Shot_2022-01-03_at_7.37.49_PM.png "Screen Shot 2022-01-03 at 7.37.49 PM.png") Now it will tell you that you successfully made an app - go ahead and click the **Done** button. ![](https://files.readme.io/ef69de0-Screen_Shot_2022-01-03_at_7.39.12_PM.png "Screen Shot 2022-01-03 at 7.39.12 PM.png") As you can see, your should be on your dashboard. You should click into it. ![](https://files.readme.io/e8d5aa8-Screen_Shot_2022-01-03_at_7.44.47_PM.png "Screen Shot 2022-01-03 at 7.44.47 PM.png") You should scroll on the left handed tool bar until you find the API Access tab. ![](https://files.readme.io/e4c6e96-Screen_Shot_2022-01-03_at_7.45.57_PM.png "Screen Shot 2022-01-03 at 7.45.57 PM.png") On the API access page, click the banner near the top of the page to head to the API Tokens page. ![](https://files.readme.io/fce58a9-Screen_Shot_2022-01-03_at_7.47.42_PM.png "Screen Shot 2022-01-03 at 7.47.42 PM.png") Here, you have access to both API tokens. Make sure to use **API token V1.0** when inputting your API token into hotglue! # App Store Connect Source: https://docs.hotglue.com/connectors/appstore # Connector Details | Name | Value | | :- | :- | | Platform | [App Store Connect](https://apple.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-appstore](https://github.com/hotgluexyz/tap-appstore) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Asana Source: https://docs.hotglue.com/connectors/asana # Connector Details | Name | Value | | :- | :- | | Platform | [Asana](https://asana.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-asana](https://github.com/hotgluexyz/tap-asana) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Asana connector. # Obtain your Asana OAuth Client ID and OAuth Client Secret To create an OAuth application, get started by [logging into Asana](https://app.asana.com/-/login). Once logged in, you can navigate to the [Developer Dashboard](https://app.asana.com/0/my-apps) and create a new OAuth app. Once created, navigate to the OAuth page. Take note of the Client ID and Client Secret, and add the following as a Redirect URL: ``` https://hotglue.xyz/callback ``` Next, you will need to select scopes. This depends on your use case for Asana. Take note of the scopes that you select here, as you will need to enter these in hotglue. Lastly, before going live with Asana, you will need to ensure that your app is set to "Any Workspace" in the "Manage Distribution" tab. This will ensure that your customers are able to authorize the connection. # Set up Asana in Hotglue In hotglue, you will need to start by updating Asana's OAuth URL via your connector settings. You will update the `tap_url` if updating **Connectors**, or the `auth_url` if updating **Sources**/**Targets**. If you're not sure which you should be updating, feel free to reach out or [consult our docs](https://docs.hotglue.com/key-concepts/connectors/connectors). To update, take the scopes that you added to your Asana OAuth app, and append them via the `scope=` parameter. For example, the below tap\_url would request "projects" and "tasks" permissions from your customers: ``` "tap_url": "https://app.asana.com/-/oauth_authorize?response_type=code&scope=projects:read tasks:read" ``` Once that's set, you're good to go! Go back to your flow, add Asana to it with your new Client ID and Client Secret, and authorize to verify the connection. # Auth0 Source: https://docs.hotglue.com/connectors/auth0 # Connector Details | Name | Value | | :- | :- | | Platform | [Auth0](https://auth0.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-auth0](https://gitlab.com/hotglue/tap-auth0) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Auth0 connector. ## Client ID, Client Secret, and Domain The first thing you need to do is log in to [Auth0](https://auth0.auth0.com/u/login/identifier?state=hKFo2SA1WnJra005U1lUdmtZSy0wb25UaXB3cXlrenNrQTlxSqFur3VuaXZlcnNhbC1sb2dpbqN0aWTZIDVsMDQ5d24xLXNickt5enhMVVRuLUVKZ1V2bERzcFJ2o2NpZNkgYkxSOVQ1YXI2bkZ0RE80ekVyR1hkb3FNQ000aU5aU1Y). They have a free trial, so if you don't have an account, you can make one. ![](https://files.readme.io/b84bc08-Screen_Shot_2022-02-16_at_2.05.15_PM.png "Screen Shot 2022-02-16 at 2.05.15 PM.png") Your home page should look something like this. On the top left side of your screen, you should click the Applications option from the navigation menu. ![](https://files.readme.io/545bde3-Screen_Shot_2022-02-16_at_2.06.00_PM.png "Screen Shot 2022-02-16 at 2.06.00 PM.png") Now, you should select Applications again from the resulting drop down. ![](https://files.readme.io/bc5ffe2-Screen_Shot_2022-02-16_at_2.10.40_PM.png "Screen Shot 2022-02-16 at 2.10.40 PM.png") On this page, click the Create Application button on the upper right side. ![](https://files.readme.io/2fb5dca-Screen_Shot_2022-02-16_at_2.11.31_PM.png "Screen Shot 2022-02-16 at 2.11.31 PM.png") You should name the application your company name, and select the Machine to Machine Applications option. This is very important as you must select the Machine to Machine option. ![](https://files.readme.io/d87731b-Screen_Shot_2022-02-16_at_2.13.36_PM.png "Screen Shot 2022-02-16 at 2.13.36 PM.png") You will then be prompted to pick an API for the app. Click on the drop down option. ![](https://files.readme.io/f3d60db-Screen_Shot_2022-02-16_at_2.14.06_PM.png "Screen Shot 2022-02-16 at 2.14.06 PM.png") You should then go ahead and select the Auth0 Management API. ![](https://files.readme.io/97bdb09-Screen_Shot_2022-02-16_at_2.17.25_PM.png "Screen Shot 2022-02-16 at 2.17.25 PM.png") You will then be asked to enable certain permissions for you app. Based on what data you want to be able to pull, this will vary. ![](https://files.readme.io/f0b9c87-Screen_Shot_2022-02-16_at_2.25.48_PM.png "Screen Shot 2022-02-16 at 2.25.48 PM.png") Since I just want to read users information, I will select the two read:users scopes. If you need to read additional data, make sure to include that with your checked off scopes! Once you are done, click Authorize. ![](https://files.readme.io/e45136d-Screen_Shot_2022-02-16_at_2.36.22_PM.png "Screen Shot 2022-02-16 at 2.36.22 PM.png") Now you will be on this page. You should head to the Settings tab of the app. ![](https://files.readme.io/6d0478a-Screen_Shot_2022-02-16_at_2.36.40_PM.png "Screen Shot 2022-02-16 at 2.36.40 PM.png") On this page, you have all three credentials you need to input into hotglue. The Auth0 Domain, the Auth0 Client ID, and the Auth0 Client Secret! Go ahead and copy these credentials into hotglue. # AWS Cognito Source: https://docs.hotglue.com/connectors/aws-cognito # Connector Details | Name | Value | | :- | :- | | Platform | [AWS Cognito](https://aws.amazon.com/cognito) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-aws-cognito](https://gitlab.com/hotglue/tap-aws-cognito) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Bexio Source: https://docs.hotglue.com/connectors/bexio # Connector Details | Name | Value | | :- | :- | | Platform | [Bexio](https://bexio.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-bexio](https://gitlab.com/hotglue/tap-bexio) | | Target Repo | [https://gitlab.com/hotglue/target-bexio](https://gitlab.com/hotglue/target-bexio) | | Tap Metrics | Usage: (low) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (high) | # BigCommerce Source: https://docs.hotglue.com/connectors/bigcommerce # Connector Details | Name | Value | | :- | :- | | Platform | [BigCommerce](https://bigcommerce.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-bigcommerce](https://gitlab.com/hotglue/tap-bigcommerce) | | Target Repo | [https://gitlab.com/hotglue/target-bigcommerce](https://gitlab.com/hotglue/target-bigcommerce) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (high) | | Unified Schema | Supported in [Ecommerce Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders) | # Credentials Setup Follow the steps below to get the credentials you need to use the BigCommerce connector. # Obtain your Consumer Key pair To get your key pair for BigCommerce, you are first going to need to log in to [BigCommerce](https://login.bigcommerce.com/login) and navigate to the home page. ![](https://files.readme.io/b505e1a-Home_page.png "Home_page.png") Navigate to Advanced Settings on the left-sided nav bar. ![](https://files.readme.io/9f42899-Advance_settings.png "Advance_settings.png") From the resulting drop down, select API Accounts. ![](https://files.readme.io/fa984e4-API_ACC_Create_API_ACC.png "API ACC_Create_API_ACC.png") Click on Create API account in the top right hand corner. ![](https://files.readme.io/4a5aaf3-API_Accounts_Sett_save.png "API Accounts_Sett_save.png") Input App name (should be your company name) and other fields. Once done, click the Save button. ![](https://files.readme.io/ab378d5-API_Cred_Secrt_key.png "API_Cred_Secrt_key.png") Copy the Client ID and Access token and Click on Done. ![](https://files.readme.io/642b01f-api_hash.png "api_hash.png") Store hash has can be found on Home → API Accounts, as pictured above. That's it! Now you have all the credentials needed for hotglue to connect to the BigCommerce API. # BigQuery Source: https://docs.hotglue.com/connectors/bigquery # Connector Details | Name | Value | | :- | :- | | Platform | [BigQuery](https://cloud.google.com/bigquery) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-bigquery](https://github.com/hotgluexyz/tap-bigquery) | | Target Repo | [https://github.com/hotgluexyz/target-bigquery](https://github.com/hotgluexyz/target-bigquery) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the BigQuery connector. # How to get your BigQuery credentials ## Enable the BigQuery API First and foremost, make sure you are logged in to the correct Google account that you would like to access BigQuery from. Once you're logged in to the correct Google account, head to the [Google Cloud Platfrom Web Console](https://console.cloud.google.com). Once you are on the home page of GCP's Web Console, head to the navigation bar on the left side of the screen. Once you open the Navigation bar, head to the **APIs & Services** tab, and select **Library** from the resulting drop down. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeR4jrLF1XzGtaGs7Fu%2F-MeRN_XEJkL-Xj7bVGI1%2F01_API_and_Services_Library-2.png?alt=media\&token=0bd4693f-3542-449a-b30a-75c71d7eb4c8) This will take you to a page where you should input **BigQuery** in the search box. Once it pops up, go ahead and click on it. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeR4jrLF1XzGtaGs7Fu%2F-MeRN_XEJkL-Xj7bVGI1%2F01_API_and_Services_Library-2.png?alt=media\&token=0bd4693f-3542-449a-b30a-75c71d7eb4c8) Now, go ahead and click the **Enable** button in order to enable the **BigQuery API**. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRQIJDsd3xHB8BGS0x%2F-MeRQceczcj_pQDp_ywp%2F03_Enable_BigQuery_API.png?alt=media\&token=58b4224f-a4c3-4e3a-942e-1868c0ff3f76) ## Authenticating with a service account It is recomended that you use a service account with the BigQuery target. To create service account credentials, take the following steps. Use the navigation bar on the left again to navigate to the **APIs & Services** tab and select **Credentials** from the resulting drop down menu. Once you are on the **Credentials** page, click the **Create Credentials** button at the top of the page, which will trigger a drop down menu. From that drop down menu, go ahead and select **Service Account**. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRQIJDsd3xHB8BGS0x%2F-MeRSBjlrbp42HlXuTtc%2F04_Create_Service_Account.png?alt=media\&token=b27c056e-0623-4b60-ac4b-9b107198ed07) Under the **Service account details**, title the account target-bigquery and click the **Create** button. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRbhk7tu9Uk7KAoGqZ%2F-MeRc3GAYeMJMpbBpoTE%2F05_Service_Account_Name.png?alt=media\&token=0bee84cd-0641-4d7d-b9f8-7c341804fe33) Under **Grant this service account access to project**, make sure that you have two roles. The first role should allow the service account to be a **BigQuery Data Editor**. This allows the target to edit the contents of the data sets (write permissions). Make sure that the second role is **BigQuery Job User**. This is a bit self explanatory, it allows the target to run jobs. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRdE7L-BH3ht-4EAd0%2F-MeRdxQeRdiNBZLlK3UK%2F06_Service_Account_Access.png?alt=media\&token=e36dc8e8-56d1-4b4b-9008-af6279e05b8a) Now, using the navigation panel again, head back to the APIs & Services tab and go the **Credentials** tab within the tab. You should see the service account you just created near the bottom of your screen. Go and click on it. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRdE7L-BH3ht-4EAd0%2F-MeRfEmEYQKx0fXOmzjh%2F07_Select_Service_Account.png?alt=media\&token=9fe39905-51d3-4621-9b41-9f7e86918516) Near the bottom of the page, you should go ahead and click the **Add Key** button which will prompt a dropdown. Once it does this, click **Create new key**. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRfUXUohmqNW2TnCoh%2F-MeRffxvRy-Eu9BcPInT%2F08_Add_Key.png?alt=media\&token=4a9d82c7-e71c-46fc-b4c8-81bb5b3b5eaf) Select **JSON** for your private key and click **Create**. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRfsTfG__nJ-keqfi-%2F-MeRfxtnTHBxYydBBNLl%2F09_JSON_Key.png?alt=media\&token=5b2ecbdc-f684-40e8-b3ac-220b7780a93c) You should go ahead and open the file. Make sure you keep this somewhere safe. This file holds the credentials that you should use to connect your BigQuery account as a target in hotglue. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRfsTfG__nJ-keqfi-%2F-MeRg80uEKs3wsYmoGyw%2F10_Download_Client_Secrets.png?alt=media\&token=79998205-86fe-475d-89eb-50284362247a) These are the credentials that are relevant for configuring your hotglue target. Paste them into their corresponding places in hotglue and you are all set! ```json theme={null} { "type": "service_account", "project_id": "acme", "private_key_id": "1**********************************f", "private_key": "-----BEGIN PRIVATE KEY-----\n*************\n*****************************\n************************n/*************************\n******************************\n*************************\n************************************\n*******************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n-----END PRIVATE KEY-----\n", "client_email": "***********@acme.iam.gserviceaccount.com", "client_id": "1************7", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/**************image 40acme.iam.gserviceaccount.com" } ``` # Target BigQuery ## Config In addition to the BigQuery credentials above, you will need to specify the dataset the target should write to: ```json theme={null} { "type": "service_account", "project_id": "acme", "private_key_id": "1**********************************f", "private_key": "-----BEGIN PRIVATE KEY-----\n*************\n*****************************\n************************n/*************************\n******************************\n*************************\n************************************\n*******************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n-----END PRIVATE KEY-----\n", "client_email": "***********@acme.iam.gserviceaccount.com", "client_id": "1************7", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/**************image 40acme.iam.gserviceaccount.com", "dataset_id": "id-of-dataset" } ``` ## target-tables-config: Set up partioning and clustering Target-BigQuery also supports an optional `target-tables-config.json` which can be written during the ETL phase. The config allows you to detail partioning and clustering logic for particular streams. ### Partitioning background A [partitioned table](https://cloud.google.com/bigquery/docs/partitioned-tables) is a special table that is divided into segments, called partitions, that make it easier to manage and query your data. By dividing a large table into smaller partitions, you can: * improve query performance, * control costs by reducing the number of bytes read by a query. You can partition BigQuery tables by: * Ingestion time: Tables are partitioned based on the data's ingestion (load) time or arrival time. * Date/timestamp/datetime: Tables are partitioned based on a TIMESTAMP, DATE, or DATETIME column. * Integer range: Tables are partitioned based on an integer column. ### Clustering background * When you create a clustered table in BigQuery, the table data is automatically organized based on the contents of one or more columns in the table’s schema. * The columns you specify are used to colocate related data. * When you cluster a table using multiple columns, the order of columns you specify is important. The order of the specified columns determines the sort order of the data. * Clustering can improve the performance of certain types of queries such as queries that use filter clauses and queries that aggregate data. * You can cluster up to 4 columns in a table ### Replication Methods There is also an optional parameter `replication_method` which can be used to determine the upserting behavior for a particular stream. Possible values are: * `append`: Adding new rows to the table (Default value) * `truncate`: Deleting all previous rows and uploading the new ones to the table * `incremental`: **Upserting** new rows into the table, using the **primary key** given by the tap connector (if it finds an old row with same key, updates it. Otherwise it inserts the new row) ### Example `target-tables-config.json` To add partioning and clustering to a given stream, you can specify the `partition_field` and `cluster_fields` values respectively. ```json theme={null} { "streams": { "contacts": { "partition_field": "updated_at", "cluster_fields": ["type", "status", "customer_id", "transaction_id"] }, "companies": { "replication_method": "truncate" } } } ``` ## Example ETL Script ```python theme={null} import gluestick as gs import os # Define standard Hotglue directories ROOT_DIR = os.environ.get("ROOT_DIR", ".") INPUT_DIR = f"{ROOT_DIR}/sync-output" OUTPUT_DIR = f"{ROOT_DIR}/etl-output" # Write a target target-tables-config if desired with open(f"{OUTPUT_DIR}/target-tables-config.json", "w") as fp: json.dump( { "streams": { "GeneralLedgerCashReport_default": {"replication_method": "truncate"}, "BalanceSheetReport": {"replication_method": "truncate"}, "CashFlowReport": {"replication_method": "truncate"}, "DailyCashFlowReport": {"replication_method": "truncate"}, } }, fp, ) # Read sync output input = gs.Reader() # Get tenant id tenant_id = os.environ.get('USER_ID', os.environ.get('TENANT', 'default')) # Iterate through the different streams in the sync output for key in eval(str(input)): input_df = input.get(key) """ Here we get the key properties, also known as the primary keys. The database export targets will utilize these primary keys when upserting data. If you wish to hardcode your choice of primary keys, you can do so here. """ key_properties = input.get_pk(key) # Include tenant_id as a field if desired input_df["tenant"] = tenant_id # Write this stream to the OUTPUT directory with the specified key_properties gs.to_singer(input_df, key, OUTPUT_DIR, keys=key_properties) ``` ## Optional config flags | Property | Type | Description | | - | - | - | | table\_suffix | String | Suffix to be added to the table name. | | validate\_records | Boolean | If true, validates records before loading. | | add\_metadata\_columns | Boolean | If true, adds metadata columns to the table. | | location | String | Specifies the location where the data will be stored. Default is "US". | | replication\_method | String | Method for replicating data. Options: `append`, `truncate`, `incremental`. Default is `append`. | | max\_cache | Integer | Maximum number of records to cache before writing to BigQuery. | | merge\_state\_messages | Boolean | If true, merges state messages. | | force\_alphanumeric\_table\_names | String | If true, replaces all non-alphanumeric characters in table names with `_` | # Target Changelog > [accordion] Target Changelog > > | Version | Notes | > | :- | :- | > | [v0.11.10](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.10) | | > | [v0.11.9](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.9) | | > | [v0.11.8](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.8) | | > | [v0.11.7](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.7) | | > | [v0.11.6](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.6) | | > | [v0.11.5](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.5) | | > | [v0.11.4](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.4) | | > | [v0.11.3](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.3) | fix infinite support | > | [v0.11.2](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.2) | | > | [v0.11.1](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.1) | | # Blackbaud Source: https://docs.hotglue.com/connectors/blackbaud # Connector Details | Name | Value | | :- | :- | | Platform | [Blackbaud](https://blackbaud.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-blackbaud](https://github.com/hotgluexyz/tap-blackbaud) | | Target Repo | [https://gitlab.com/hotglue/target-blackbaud](https://gitlab.com/hotglue/target-blackbaud) | | Tap Metrics | Usage: (low) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (medium) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| | Target Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Credentials Setup The Blackbaud connector uses the [SKY API](https://developer.blackbaud.com/skyapi/docs/authorization) OAuth 2.0 flow to read from and write to your customers' Blackbaud environments. To use it with hotglue, you need a [SKY Developer account](https://developer.blackbaud.com/skyapi/account), a SKY API subscription key, a registered SKY application, the application's OAuth credentials, and at least one hotglue callback URL configured as a redirect URI. The person setting this up should be able to create and manage SKY applications in the Blackbaud developer portal, subscribe to the relevant SKY API product, and—if needed—have a Blackbaud user with Marketplace admin permissions connect the application to the relevant environment. ## 1. Create a SKY Developer account Sign in to the [SKY Developer account](https://developer.blackbaud.com/skyapi/account) portal. If you do not already have a Blackbaud ID, you are prompted to create one when you sign up. See the [SKY API basics](https://developer.blackbaud.com/skyapi/docs/basics/) documentation for more background on developer accounts and Blackbaud IDs. Once signed in, you land on the Developer account page. From here, you can open **My applications** to create and manage your SKY applications, or **My subscriptions** to manage API subscription keys. ![Blackbaud SKY Developer account portal with My applications](https://mintcdn.com/hotglue/N-4I4VGQmLbD_oFN/images/Blackbaud-Dev-Portal.jpeg?fit=max\&auto=format\&n=N-4I4VGQmLbD_oFN\&q=85\&s=20c1b0d4e4dcfa0f4e6656930b7e843a) Sign in to the SKY Developer account portal, then open My applications or My subscriptions ## 2. Get a SKY API subscription key Blackbaud requires a subscription key on every SKY API request. In the developer portal, open **My subscriptions**, subscribe to the **Standard APIs** product (or the API product that covers the endpoints your integration uses), and copy either the primary or secondary key. The tap expects this value as `subscription_key`, and Blackbaud sends it on requests as the `Bb-Api-Subscription-Key` header. See Blackbaud's [My subscriptions](https://webfiles-sc1.blackbaud.com/files/support/helpfiles/skydev/content/plat-skydev-subscriptions.html) docs for details on subscribing and finding your keys. ![Blackbaud My subscriptions page showing Standard APIs primary and secondary access keys](https://mintcdn.com/hotglue/N-4I4VGQmLbD_oFN/images/BlackBauld-Subscription-Keys.jpeg?fit=max\&auto=format\&n=N-4I4VGQmLbD_oFN\&q=85\&s=9f4fd8c88800526b905406c0e71f2fcc) Copy the primary or secondary access key from your Standard APIs subscription ## 3. Create a SKY application A [SKY application](https://developer.blackbaud.com/skyapi/docs/applications) represents your integration in Blackbaud and is required to make SKY API calls. Creating an application produces the OAuth credentials hotglue needs during authorization. From **My applications**, click **+ New application** and fill out the required fields: * **Application name** * **Application details** * **Publisher** (public organization name) * **Application website URL** An application logo is optional. Click **Save** when you are done. ![Blackbaud Add application modal with required fields](https://mintcdn.com/hotglue/N-4I4VGQmLbD_oFN/images/Blackbaud-Step1.jpeg?fit=max\&auto=format\&n=N-4I4VGQmLbD_oFN\&q=85\&s=4325a83f35fdee0d34a5fc88977daf89) Create a new SKY application in the Blackbaud developer portal ## 4. Copy OAuth credentials Open your application and copy the credentials from the application page: * **Application ID** → hotglue `client_id` * **Primary application secret** → hotglue `client_secret` The Application ID is not sensitive and can be shared with Blackbaud admins who need to connect your app. The application secret is sensitive — treat it like a password and do not share it. Blackbaud provides primary and secondary secrets so you can rotate credentials; see [Application secrets](https://webfiles-sc1.blackbaud.com/files/support/helpfiles/skydev/content/plat-skydev-apps-secrets.html) for rotation guidance. ![Blackbaud application page with Application ID and client secret](https://mintcdn.com/hotglue/N-4I4VGQmLbD_oFN/images/Blackbaud-Step2.jpeg?fit=max\&auto=format\&n=N-4I4VGQmLbD_oFN\&q=85\&s=582f393444a7483b85fe2e2f1db16a37) Copy the Application ID and Primary application secret for hotglue ## 5. Configure redirect URIs In your application settings, open **Redirect URIs** and add the hotglue callback URL for your environment. Blackbaud requires the OAuth `redirect_uri` to match one of your registered URIs exactly, including trailing slashes. See the [Authorization](https://developer.blackbaud.com/skyapi/docs/authorization) and [Redirect URIs](https://help.blackbaud.com/docs/0/assets/skydev/content/plat-skydev-apps-settings-redirect-uris.html) documentation for details. Add the callback URL that matches where your hotglue environment runs: ```text theme={null} https://hotglue.xyz/callback ``` If you use a [custom OAuth callback domain](https://docs.hotglue.com/environment-settings/white-label) instead of `hotglue.xyz`, add that callback URL here as well. ![Blackbaud Redirect URIs settings with hotglue callback URLs](https://mintcdn.com/hotglue/N-4I4VGQmLbD_oFN/images/Blackbaud-Step3.jpeg?fit=max\&auto=format\&n=N-4I4VGQmLbD_oFN\&q=85\&s=5a7ec4611bf6eba585651d8da6f06249) Add hotglue callback URLs as redirect URIs ## 6. Connect the application in Blackbaud Before your application can access data in a Blackbaud environment, it must be connected to that environment. If you are integrating with a customer's Blackbaud organization, a user with Marketplace admin permissions must connect the app for you. To connect the application: 1. Open the [Manage applications](https://help.blackbaud.com/docs/0/assets/marketplace/content/plat-market-manage-apps.html) page in the Blackbaud Marketplace. 2. Use **Connect app** and paste your application's ID. 3. Confirm the connection. See [Connect an application](https://webfiles-sc1.blackbaud.com/files/support/helpfiles/marketplace/content/plat-market-connect-app.html) for step-by-step instructions. API access is further limited by the consenting user's security permissions within Blackbaud. If you have access to the SKY Developer Cohort sandbox environment, your application may already be connected and you can skip this step. ## 7. Add Blackbaud to hotglue Once you have your subscription key, OAuth credentials, and redirect URIs configured: 1. Go to **Settings** > **Connectors** in your hotglue environment. 1. Open **Bi-Directional Connectors** if you use bi-directional flows (`linkedConnectors`), then search for `Blackbaud`. 2. Open **Sources & Targets** if you use one-way source or target flows (`linkedSources` / `linkedTargets`), then search for `Blackbaud`. 2. Add your subscription key to the Blackbaud JSON definition: * If modifying a **Connector** (v2), set `options.config.subscription_key` to your Blackbaud subscription\_key value. * If modifying a **Source** or **Target** (v1), set `config.subscription_key` to your Blackbaud subscription\_key value. 3. Save the definition. See [Connector management](https://docs.hotglue.com/key-concepts/connectors/v2-connectors/management), [Connector settings](https://docs.hotglue.com/key-concepts/connectors/v2-connectors/settings), [Source settings](https://docs.hotglue.com/key-concepts/connectors/v1-sources/settings), and [Target settings](https://docs.hotglue.com/key-concepts/connectors/v1-targets/settings) for details on configuring connectors in your environment. ## 8. Authorize and enable the connector 1. Add Blackbaud to your flow. 2. Enter your Blackbaud **Application ID** as the **OAuth Client ID** and your **Primary application secret** as the **OAuth Client Secret**. 3. Save and complete authorization with a test Blackbaud user. This enables the connector in your environment. ![hotglue Blackbaud source credentials form with OAuth Client ID and OAuth Client Secret fields](https://mintcdn.com/hotglue/N-4I4VGQmLbD_oFN/images/BlackBauld-Hotglue-Connect.jpeg?fit=max\&auto=format\&n=N-4I4VGQmLbD_oFN\&q=85\&s=64bc85f665f8cb547fea41dcfe479d4c) Enter your Blackbaud Application ID and application secret in the hotglue Credentials tab hotglue stores the OAuth `refresh_token` automatically after a successful authorization. You do not need to provide it manually. After setup, your end users authorize Blackbaud through the standard OAuth consent flow when they link their account. After this you're all set to go! # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.4 - Bump Singer SDK version](https://github.com/hotgluexyz/tap-blackbaud/releases/tag/v0.0.4) | Bump Singer SDK version | > | [v0.0.3 - Avoid making extra requests unless selected in catalog](https://github.com/hotgluexyz/tap-blackbaud/releases/tag/v0.0.3) | - Updated tap to avoid pulling `fundraiser_assignment` and other per-constituent fields unless they have been selected in the catalog | > | [v0.0.2 - Add support for Education, Lifetime Giving, and Fundraiser Assignment](https://github.com/hotgluexyz/tap-blackbaud/releases/tag/v0.0.2) | - Added support for Education, Lifetime Giving, and Fundraiser Assignment - Also added "online\_presence" and "preferred\_name" - Removing "suffix" (which according to the documentation is not part of the schema) | # Azure Blob Storage Source: https://docs.hotglue.com/connectors/blob-storage # Connector Details | Name | Value | | :- | :- | | Platform | [Azure Blob Storage](https://azure.microsoft.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-blob-storage](https://github.com/hotgluexyz/tap-blob-storage) | | Target Repo | [https://github.com/hotgluexyz/target-blob-storage](https://github.com/hotgluexyz/target-blob-storage) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Azure Blob Storage connector. # How to get your Blob Storage credentials The Blob Storage requires only a connection string to connect to your Blob Storage. To find your connection string, log in to your Azure Portal and navigate to [your Storage Accounts Dashboard](https://portal.azure.com/#browse/Microsoft.Storage%2FStorageAccounts), ![Azure Storage Accounts](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/AzureStorageAccts.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=7314e9e2ffcebad2e46e5a97550c7dae) Next, select your Storage Account, and navigate to **Security + Networking > Access Keys** and copy one of your connection strings. You'll then paste this connection string directly into the Hotglue dashboard or into a config object, depending on how you are linking your connector. ![Azure Connection String](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/AzureConnectString.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=767b30bf990c702edc0349507c2cb038) # Target Blob Storage ## Config In addition to the `connect_string` parameter, you should specify the following fields when connecting: ```json theme={null} { "connect_string": "...", "container": "...", // Container name to write to "path_prefix": "...", // Directory to insert files into "overwrite": true // Whether to overwrite files (defaults False) } ``` ## Example ETL Script ```python theme={null} import gluestick as gs import os import time # Define standard Hotglue directories ROOT_DIR = os.environ.get("ROOT_DIR", ".") INPUT_DIR = f"{ROOT_DIR}/sync-output" OUTPUT_DIR = f"{ROOT_DIR}/etl-output" # Read sync output input = gs.Reader() # Get tenant id tenant_id = os.environ.get('USER_ID', os.environ.get('TENANT', 'default')) # Possible values parquet, singer, csv, json, jsonl EXPORT_FORMAT = "parquet" # Iterate through the different streams in the sync output for key in eval(str(input)): input_df = input.get(key) # Include tenant_id as a field if desired input_df["tenant"] = tenant_id # Create a unique file name timestamp = int(time.time()) # Unix Time stamp file_name = f"{tenant_id}_{key}_{timestamp}" # Write tenantid_streamname_timestamp.parquet gs.to_export(input_df, file_name, OUTPUT_DIR, export_format=EXPORT_FORMAT) ``` # Target Changelog > [accordion] Target Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.1](https://github.com/hotgluexyz/target-blob-storage/releases/tag/v0.0.1) | | # bol.com Source: https://docs.hotglue.com/connectors/bol # Connector Details | Name | Value | | :- | :- | | Platform | [bol.com](https://bol.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-bol](https://gitlab.com/hotglue/tap-bol) | | Tap Metrics | Usage: (medium) Success Rate: (high) | # BQE Source: https://docs.hotglue.com/connectors/bqe # Connector Details | Name | Value | | :- | :- | | Platform | [BQE](https://bqe.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/chauncywilson/tap-bqe](https://gitlab.com/chauncywilson/tap-bqe) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Braintree Source: https://docs.hotglue.com/connectors/braintree # Connector Details | Name | Value | | :- | :- | | Platform | [Braintree](https://braintreepayments.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/singer-io/tap-braintree](https://github.com/singer-io/tap-braintree) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Campaign Monitor Source: https://docs.hotglue.com/connectors/campaign-monitor # Connector Details | Name | Value | | :- | :- | | Platform | [Campaign Monitor](https://campaignmonitor.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-campaign-monitor](https://gitlab.com/hotglue/tap-campaign-monitor) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Campaign Monitor connector. # Obtain your Client ID and API Key ## Client ID and API Key The first thing you need to do is log in to [Campaign Monitor](https://login.createsend.com/l?_ga). They have a free trial, so if you don't have an account, you can make one. ![](https://files.readme.io/c291ecf-Screen_Shot_2022-01-24_at_7.09.25_PM.png "Screen Shot 2022-01-24 at 7.09.25 PM.png") Your home page should look something like this. On the top right side of your screen, you should click the account icon. ![](https://files.readme.io/b2b52ad-Screen_Shot_2022-01-24_at_7.10.07_PM.png "Screen Shot 2022-01-24 at 7.10.07 PM.png") Now, you should select account settings from the resulting drop down. ![](https://files.readme.io/cbece90-Screen_Shot_2022-01-24_at_7.10.42_PM.png "Screen Shot 2022-01-24 at 7.10.42 PM.png") On this page, head to the API Keys section. ![](https://files.readme.io/5d675c5-Screen_Shot_2022-01-24_at_7.12.54_PM.png "Screen Shot 2022-01-24 at 7.12.54 PM.png") Here are the credentials you need to plug into hotglue! # Capsule Source: https://docs.hotglue.com/connectors/capsulecrm # Connector Details | Name | Value | | :- | :- | | Platform | [Capsule](https://capsulecrm.com) | | Auth Type | OAuth | | Direction | Read | | Triggers | Supported (1 triggers available by default) | | Tap Repo | [https://gitlab.com/hotglue/tap-capsulecrm](https://gitlab.com/hotglue/tap-capsulecrm) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Chargebee Source: https://docs.hotglue.com/connectors/chargebee # Connector Details | Name | Value | | :- | :- | | Platform | [Chargebee](https://chargebee.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-chargebee](https://github.com/hotgluexyz/tap-chargebee) | | Tap Metrics | Usage: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Chargebee connector. To obtain your Chargebee credentials, you must first [login to Chargebee](https://app.chargebee.com/login). If you don't currently have an account, you can make a free one [here](https://www.chargebee.com/trial-signup/?ref=Launch). ## Site Name ![](https://files.readme.io/3c40625-Screen_Shot_2021-12-15_at_2.29.43_PM.png "Screen Shot 2021-12-15 at 2.29.43 PM.png") Once you do login, you should be greeted with a page similar to this. The first credential you will need for hotglue is your site name. You can find that in the top right hand corner of your screen. **Note: If you are using a testing account and/or sandbox, your site name will be yoursitename-test. You can see in the example above that the account we are connecting is a test account. If you are not sure if you have a test account, you can also check the url of your site. The beginning of the URL is also your site name.** ## API Key ![](https://files.readme.io/3b16982-Screen_Shot_2021-12-15_at_2.46.13_PM.png "Screen Shot 2021-12-15 at 2.46.13 PM.png") The next credential you will need is your API key. From the home page, you should click the **Settings** dropdown from the navigation bar on the left hand side. ![](https://files.readme.io/6f99b76-Screen_Shot_2021-12-15_at_2.47.42_PM.png "Screen Shot 2021-12-15 at 2.47.42 PM.png") From the resulting drop down, you should select the **Configure Chargebee tab**. ![](https://files.readme.io/5c41ea2-Screen_Shot_2021-12-15_at_2.49.37_PM.png "Screen Shot 2021-12-15 at 2.49.37 PM.png") On this page, scroll down until you get to the **API Keys and Webhooks section**. You should then click on the **API keys** option. ![](https://files.readme.io/684c60d-Screen_Shot_2021-12-15_at_2.51.03_PM.png "Screen Shot 2021-12-15 at 2.51.03 PM.png") You will now be on a page where you can create new API Keys. You should go ahead and create a new key for hotglue. Do this by click on the **Add API Key** button. ![](https://files.readme.io/62c12b4-Screen_Shot_2021-12-15_at_2.58.45_PM.png "Screen Shot 2021-12-15 at 2.58.45 PM.png") You will now be asked what kind of key you want to create. You should go ahead and select the **Full-Access Key** option. ![](https://files.readme.io/38225b8-Screen_Shot_2021-12-15_at_3.00.17_PM.png "Screen Shot 2021-12-15 at 3.00.17 PM.png") Now go ahead and name your key **hotglue**. Subsequently, you should click **Create Key**. ![](https://files.readme.io/c1a2aa9-Screen_Shot_2021-12-15_at_3.03.45_PM.png "Screen Shot 2021-12-15 at 3.03.45 PM.png") Now you have your API Key! Make sure to copy this into hotglue. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.0.33](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.33) | | > | [v1.0.32](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.32) | | > | [v1.0.31](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.31) | Add ramps stream | > | [v1.0.30](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.30) | | > | [v1.0.29](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.29) | | > | [v1.0.27](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.27) | | > | [v1.0.26](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.26) | | > | [v1.0.25](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.25) | | > | [v1.0.24](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.24) | | > | [v1.0.22](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.22) | | > | [v1.0.21](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.21) | | > | [v1.0.20](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.20) | | > | [v1.0.19](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.19) | | > | [v1.0.18](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.18) | | > | [v1.0.17](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.17) | | > | [v1.0.16](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.16) | | > | [v1.0.15](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.15) | | > | [v1.0.14](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.14) | | > | [v1.0.13](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.13) | | > | [v1.0.12](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.12) | | > | [v1.0.11](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.11) | | > | [v1.0.10](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.10) | | > | [v1.0.9](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.9) | | > | [v1.0.8 - Bug fixes](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.8) | - Update tap to handle invalid responses from Chargebee API with retries | > | [v1.0.7 - Add exchange rate to credit notes](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.7) | - Add exchange rate to credit notes | > | [v1.0.2 - Add Product Catalog 2.0 support](https://github.com/hotgluexyz/tap-chargebee/releases/tag/v1.0.2) | Adds support for new Chargebee product catalog | # Chargify Source: https://docs.hotglue.com/connectors/chargify # Connector Details | Name | Value | | :- | :- | | Platform | [Chargify](https://chargify.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/singer-io/tap-chargify](https://github.com/singer-io/tap-chargify) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Cin7 Source: https://docs.hotglue.com/connectors/cin7 # Connector Details | Name | Value | | :- | :- | | Platform | [Cin7](https://cin7.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-cin7](https://gitlab.com/hotglue/tap-cin7) | | Target Repo | [https://gitlab.com/hotglue/target-cin7](https://gitlab.com/hotglue/target-cin7) | | Tap Metrics | Usage: (high) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (high) | # ClickUp Source: https://docs.hotglue.com/connectors/clickup # Connector Details | Name | Value | | :- | :- | | Platform | [ClickUp](https://clickup.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/AutoIDM/tap-clickup](https://github.com/AutoIDM/tap-clickup) | | Target Repo | [https://gitlab.com/hotglue/target-clickup](https://gitlab.com/hotglue/target-clickup) | | Tap Metrics | Usage: (low) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the ClickUp connector. ## API Key The first thing you need to do is log in to [ClickUp](https://clickup.com). They have a free tier, so if you don't have an account, you can make one. ![](https://files.readme.io/06e13a6-Screen_Shot_2021-11-17_at_11.56.44_AM.png "Screen Shot 2021-11-17 at 11.56.44 AM.png") Your home page should look something like this. On the bottom left side of the screen, you should click your icon. ![](https://files.readme.io/6f4bfdb-Screen_Shot_2021-11-17_at_12.40.08_PM.png "Screen Shot 2021-11-17 at 12.40.08 PM.png") You should now see a menu of items. You should go ahead and select the **My Settings** option. ![](https://files.readme.io/840de92-Screen_Shot_2021-11-17_at_12.40.41_PM.png "Screen Shot 2021-11-17 at 12.40.41 PM.png") Now you should be in the **My Settings** page. From here, you should scroll down on the left-sided tool bar until you reach the **My Apps** category. Once you've reached the category, select the **Apps** section. ![](https://files.readme.io/56c939e-Screen_Shot_2021-11-17_at_12.41.58_PM.png "Screen Shot 2021-11-17 at 12.41.58 PM.png") Now, you should be on a page where you can generate an API token. Go ahead and click the **Generate** button in order to create your API Token. ![](https://files.readme.io/0ebf60e-Screen_Shot_2021-11-17_at_12.44.05_PM.png "Screen Shot 2021-11-17 at 12.44.05 PM.png") You have now generated your API Token. Go ahead and copy it. ![](https://files.readme.io/22f16df-Screen_Shot_2021-11-17_at_12.45.41_PM.png "Screen Shot 2021-11-17 at 12.45.41 PM.png") Now you should go ahead and take the credential you generated in put it in hotglue! # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.23](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.23) | ## What's Changed \* Patch is\_boolean\_type to fix custom\_fields values by @claudenigma in [https://github.com/AutoIDM/tap-clickup/pull/150](https://github.com/AutoIDM/tap-clickup/pull/150) ## New Contributors \* @claudenigma made their first contribution in [https://github.com/AutoIDM/tap-clickup/pull/150](https://github.com/AutoIDM/tap-clickup/pull/150) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.22...v0.0.23](https://github.com/AutoIDM/tap-clickup/compare/v0.0.22...v0.0.23) | > | [v0.0.22](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.22) | ## What's Changed \* Task time\_estimate can be a floating point number by @mcarriere in [https://github.com/AutoIDM/tap-clickup/pull/147](https://github.com/AutoIDM/tap-clickup/pull/147) \* Release v0.0.22 by @visch in [https://github.com/AutoIDM/tap-clickup/pull/148](https://github.com/AutoIDM/tap-clickup/pull/148) ## New Contributors \* @mcarriere made their first contribution in [https://github.com/AutoIDM/tap-clickup/pull/147](https://github.com/AutoIDM/tap-clickup/pull/147) , thank you! **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.21...v0.0.22](https://github.com/AutoIDM/tap-clickup/compare/v0.0.21...v0.0.22) | > | [v0.0.21](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.21) | ## What's Changed \* Weekly workflow run by @sebastianswms in [https://github.com/AutoIDM/tap-clickup/pull/141](https://github.com/AutoIDM/tap-clickup/pull/141) \* This updates the SDK which fixes a problem where incremental keys were not being automatically added to the selected fields for a stream causing [https://github.com/AutoIDM/tap-clickup/issues/140](https://github.com/AutoIDM/tap-clickup/issues/140) ## New Contributors \* @sebastianswms made their first contribution in [https://github.com/AutoIDM/tap-clickup/pull/141](https://github.com/AutoIDM/tap-clickup/pull/141) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.20...v0.0.21](https://github.com/AutoIDM/tap-clickup/compare/v0.0.20...v0.0.21) | > | [v0.0.20](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.20) | ## What's Changed \* Time Entries docs update by @visch in [https://github.com/AutoIDM/tap-clickup/pull/135](https://github.com/AutoIDM/tap-clickup/pull/135) \* 3.10, 3.11 support by @visch in [https://github.com/AutoIDM/tap-clickup/pull/136](https://github.com/AutoIDM/tap-clickup/pull/136) \* date\_done added by @visch in [https://github.com/AutoIDM/tap-clickup/pull/138](https://github.com/AutoIDM/tap-clickup/pull/138) Thank you to @JohannesRudolph \* label\_fix by @visch in [https://github.com/AutoIDM/tap-clickup/pull/139](https://github.com/AutoIDM/tap-clickup/pull/139) Thank you to @balmasi **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.19...v0.0.20](https://github.com/AutoIDM/tap-clickup/compare/v0.0.19...v0.0.20) | > | [v0.0.19](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.19) | ## What's Changed \* Update test comments by @visch in [https://github.com/AutoIDM/tap-clickup/pull/124](https://github.com/AutoIDM/tap-clickup/pull/124) \* Fixes Schema flattening issues by @visch in [https://github.com/AutoIDM/tap-clickup/pull/129](https://github.com/AutoIDM/tap-clickup/pull/129) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.18...v0.0.19](https://github.com/AutoIDM/tap-clickup/compare/v0.0.18...v0.0.19) | > | [v0.0.18](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.18) | ## What's Changed \* v0.0.17 by @visch in [https://github.com/AutoIDM/tap-clickup/pull/120](https://github.com/AutoIDM/tap-clickup/pull/120) \* Fixed Schema issues @visch in [https://github.com/AutoIDM/tap-clickup/pull/122](https://github.com/AutoIDM/tap-clickup/pull/122) \* Release 0.0.18 by @visch in [https://github.com/AutoIDM/tap-clickup/pull/123](https://github.com/AutoIDM/tap-clickup/pull/123) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.17...v0.0.18](https://github.com/AutoIDM/tap-clickup/compare/v0.0.17...v0.0.18) | > | [v0.0.17](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.17) | ## What's Changed \* State for Tasks by @visch in [https://github.com/AutoIDM/tap-clickup/pull/117](https://github.com/AutoIDM/tap-clickup/pull/117) \* fixed custom fields Double by adding number to the schema by @lpearson-trek10 in [https://github.com/AutoIDM/tap-clickup/pull/116](https://github.com/AutoIDM/tap-clickup/pull/116) \* Dropped support for python 3.6 ## New Contributors \* @lpearson-trek10 made their first contribution in [https://github.com/AutoIDM/tap-clickup/pull/116](https://github.com/AutoIDM/tap-clickup/pull/116) . Thank you! **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.16...v0.0.17](https://github.com/AutoIDM/tap-clickup/compare/v0.0.16...v0.0.17) Pypi: [https://pypi.org/project/tap-clickup/0.0.17/](https://pypi.org/project/tap-clickup/0.0.17/) | > | [v0.0.16](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.16) | ## What's Changed \* Fix for time\_entries by @visch in [https://github.com/AutoIDM/tap-clickup/pull/113](https://github.com/AutoIDM/tap-clickup/pull/113) \* v0.0.16 by @visch in [https://github.com/AutoIDM/tap-clickup/pull/115](https://github.com/AutoIDM/tap-clickup/pull/115) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.15...v0.0.16](https://github.com/AutoIDM/tap-clickup/compare/v0.0.15...v0.0.16) | > | [v0.0.15](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.15) | ## What's Changed \* Fixed Lint issues, and removed State from docs by @visch in [https://github.com/AutoIDM/tap-clickup/pull/102](https://github.com/AutoIDM/tap-clickup/pull/102) \* Remove python 3.6 by @visch in [https://github.com/AutoIDM/tap-clickup/pull/107](https://github.com/AutoIDM/tap-clickup/pull/107) \* Added a ref Resolver by @visch in [https://github.com/AutoIDM/tap-clickup/pull/105](https://github.com/AutoIDM/tap-clickup/pull/105) \* Added time entries stream by @visch in [https://github.com/AutoIDM/tap-clickup/pull/110](https://github.com/AutoIDM/tap-clickup/pull/110) \* v0.0.15 by @visch in [https://github.com/AutoIDM/tap-clickup/pull/111](https://github.com/AutoIDM/tap-clickup/pull/111) \* \* Trek10 logo added by @visch in [https://github.com/AutoIDM/tap-clickup/pull/106](https://github.com/AutoIDM/tap-clickup/pull/106) \* \* License update by @visch in [https://github.com/AutoIDM/tap-clickup/pull/103](https://github.com/AutoIDM/tap-clickup/pull/103) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.14...v0.0.15](https://github.com/AutoIDM/tap-clickup/compare/v0.0.14...v0.0.15) | > | [v0.0.14](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.14) | ## What's Changed \* Resolve Issue #92 - Schema Validation Failure by @drewipson in [https://github.com/AutoIDM/tap-clickup/pull/94](https://github.com/AutoIDM/tap-clickup/pull/94) \* Fix schema issue with for shared hierarchy and custom field items by @LucasZielke in [https://github.com/AutoIDM/tap-clickup/pull/96](https://github.com/AutoIDM/tap-clickup/pull/96) \* Added Archived Streams for Lists, Folders, Spaces \* Combined Task Streams ## New Contributors \* @drewipson made their first contribution in [https://github.com/AutoIDM/tap-clickup/pull/94](https://github.com/AutoIDM/tap-clickup/pull/94) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.13...v0.0.14](https://github.com/AutoIDM/tap-clickup/compare/v0.0.13...v0.0.14) | > | [v0.0.13](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.13) | ## What's Changed \* Fixed url param error by @LucasZielke in [https://github.com/AutoIDM/tap-clickup/pull/84](https://github.com/AutoIDM/tap-clickup/pull/84) \* 0.0.13 release by @visch in [https://github.com/AutoIDM/tap-clickup/pull/85](https://github.com/AutoIDM/tap-clickup/pull/85) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.12...v0.0.13](https://github.com/AutoIDM/tap-clickup/compare/v0.0.12...v0.0.13) | > | [v0.0.12](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.12) | ## What's Changed \* Archived bug introduced in v0.0.11 , fixed. Archived tasks split out as archived=true doesn't include non archive… by @visch in [https://github.com/AutoIDM/tap-clickup/pull/81](https://github.com/AutoIDM/tap-clickup/pull/81) \* Added two new streams for \_archived tasks \* 0.0.12 by @visch in [https://github.com/AutoIDM/tap-clickup/pull/82](https://github.com/AutoIDM/tap-clickup/pull/82) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.11...v0.0.12](https://github.com/AutoIDM/tap-clickup/compare/v0.0.11...v0.0.12) | > | [v0.0.11](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.11) | ## What's Changed \* folder\_tasks were missing closed, and subtasks. Both folderless and f… by @visch in [https://github.com/AutoIDM/tap-clickup/pull/77](https://github.com/AutoIDM/tap-clickup/pull/77) \* Version bump 0.0.11 by @visch in [https://github.com/AutoIDM/tap-clickup/pull/78](https://github.com/AutoIDM/tap-clickup/pull/78) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.10...v0.0.11](https://github.com/AutoIDM/tap-clickup/compare/v0.0.10...v0.0.11) | > | [v0.0.10](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.10) | ## What's Changed \* Custom fields can also be jsonobjects, specefically manual\_progress\_t… by @visch in [https://github.com/AutoIDM/tap-clickup/pull/73](https://github.com/AutoIDM/tap-clickup/pull/73) \* 0.0.10 version bump by @visch in [https://github.com/AutoIDM/tap-clickup/pull/75](https://github.com/AutoIDM/tap-clickup/pull/75) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.9...v0.0.10](https://github.com/AutoIDM/tap-clickup/compare/v0.0.9...v0.0.10) | > | [v0.0.9](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.9) | ## What's Changed \* Changed default Python runner for CI to python 3.9 by @visch in [https://github.com/AutoIDM/tap-clickup/pull/63](https://github.com/AutoIDM/tap-clickup/pull/63) \* Followed Stich documentation guidelines by @visch in [https://github.com/AutoIDM/tap-clickup/pull/66](https://github.com/AutoIDM/tap-clickup/pull/66) \* Remove unused lists stream by @visch in [https://github.com/AutoIDM/tap-clickup/pull/67](https://github.com/AutoIDM/tap-clickup/pull/67) \* Added PyPi to ReadMe, and added additional information on the pypi di… by @visch in [https://github.com/AutoIDM/tap-clickup/pull/68](https://github.com/AutoIDM/tap-clickup/pull/68) \* Cleanup unused code, removed file that's not needed by @visch in [https://github.com/AutoIDM/tap-clickup/pull/69](https://github.com/AutoIDM/tap-clickup/pull/69) \* Added Folder Lists for Custom Fields, changing the output tables for … by @visch in [https://github.com/AutoIDM/tap-clickup/pull/70](https://github.com/AutoIDM/tap-clickup/pull/70) \* Bump version to 0.0.9 by @visch in [https://github.com/AutoIDM/tap-clickup/pull/71](https://github.com/AutoIDM/tap-clickup/pull/71) **Full Changelog**: [https://github.com/AutoIDM/tap-clickup/compare/v0.0.8...v0.0.9](https://github.com/AutoIDM/tap-clickup/compare/v0.0.8...v0.0.9) | > | [v0.0.8](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.8) | Fixed Shared Hierarchy bug that was caught by target-stitch. Two issues solved 1. Upgraded SingerSDK as [https://gitlab.com/meltano/sdk/-/blob/main/CHANGELOG.md#changes-3](https://gitlab.com/meltano/sdk/-/blob/main/CHANGELOG.md#changes-3) was causing key-properties to be null for shared hierarchy 2. Updated the Shared Hirerarchy json to match the data we have been able to see so far. The API docs don't give a lot of insight into what that data is going to look like | > | [v0.0.7 (not released to pypi)](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.7) | Fixed Shared Hierarchy bug that was caught by target-stitch. Two issues solved 1. Upgraded SingerSDK as [https://gitlab.com/meltano/sdk/-/blob/main/CHANGELOG.md#changes-3](https://gitlab.com/meltano/sdk/-/blob/main/CHANGELOG.md#changes-3) was causing key-properties to be null for shared hierarchy 2. Updated the Shared Hirerarchy json to match the data we have been able to see so far. The API docs don't give a lot of insight into what that data is going to look like | > | [v0.0.6](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.6) | Removed date-time format! Thank you @LucasZielke | > | [v0.0.5](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.5) | | > | [v0.0.4](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.4) | | > | [v0.0.3](https://github.com/AutoIDM/tap-clickup/releases/tag/v0.0.3) | | # Clockify Source: https://docs.hotglue.com/connectors/clockify # Connector Details | Name | Value | | :- | :- | | Platform | [Clockify](https://clockify.me) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-clockify](https://github.com/hotgluexyz/tap-clockify) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Clockify connector. ## Workspace The first credential we will grab is the Workspace name. To do that, you need to go and create a Clockify account (there is a free plan that you can utilize). ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MezknEIal-zpYLiJQCm%2F-MezlLhJiuyObA4OCLOF%2FScreen%20Shot%202021-07-19%20at%201.14.43%20PM.png?alt=media\&token=be9a107b-7496-4152-9420-87dd7f41377e) Once you log in, you will see this page. In the top right will be the name of your workspace. This is the name that you should put into hotglue. ## API Key To get to API key, you need to remain on the home page of Clockify. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MezknEIal-zpYLiJQCm%2F-Mezlpn3-rYluml21fLm%2FScreen%20Shot%202021-07-19%20at%201.18.31%20PM.png?alt=media\&token=b7bf1c02-2b0c-41c6-bdb0-020ebefa7084) Go to the top right corner and click the circular emblem with the initals of the account owner. This will prompt a drop down. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MezknEIal-zpYLiJQCm%2F-Mezm7CmdmeZhHvoRN7u%2FScreen%20Shot%202021-07-19%20at%201.19.49%20PM.png?alt=media\&token=8ee7f53b-45ea-4b2e-86f7-ea8e815a726b) Next, you will need to head to your Profile settings by clicking on the option from the drop down. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MezknEIal-zpYLiJQCm%2F-Mezn1aEhaF4aGGBz_kl%2FScreen%20Shot%202021-07-19%20at%201.21.27%20PM.png?alt=media\&token=967c293c-8111-42d8-b078-70ae8347aac2) On the Profile settings page, scroll down until you see the API section. You should go ahead and click the Generate button to create an API key. Once it generates, copy it and paste it into hotglue! # Close Source: https://docs.hotglue.com/connectors/closeio # Connector Details | Name | Value | | :- | :- | | Platform | [Close](https://close.com) | | Auth Type | API Keys | | Direction | Read | | Triggers | Supported (4 triggers available by default) | | Tap Repo | [https://github.com/singer-io/tap-closeio](https://github.com/singer-io/tap-closeio) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Google Cloud Storage Source: https://docs.hotglue.com/connectors/cloud-storage # Connector Details | Name | Value | | :- | :- | | Platform | [Google Cloud Storage](https://cloud.google.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-cloud-storage](https://github.com/hotgluexyz/tap-cloud-storage) | | Target Repo | [https://github.com/hotgluexyz/target-cloud-storage](https://github.com/hotgluexyz/target-cloud-storage) | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (low) | # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.0.4](https://github.com/hotgluexyz/tap-cloud-storage/releases/tag/v1.0.4) | | > | [v1.0.3](https://github.com/hotgluexyz/tap-cloud-storage/releases/tag/v1.0.3) | | > | [v1.0.2 - Fix Path issues](https://github.com/hotgluexyz/tap-cloud-storage/releases/tag/v1.0.2) | - Use pathlib to manage paths correctly | > | [v1.0.1 - Ignore directories](https://github.com/hotgluexyz/tap-cloud-storage/releases/tag/v1.0.1) | Filter out directories returned in `list_blobs` using `key` | # CMiC Source: https://docs.hotglue.com/connectors/cmic # Connector Details | Name | Value | | :- | :- | | Platform | [CMiC](https://www.cmicglobal.com/) | | Auth Type | OAuth 2.0 Client Credentials | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-cmic](https://github.com/hotgluexyz/tap-cmic) | | Target Repo | [https://github.com/hotgluexyz/target-cmic](https://github.com/hotgluexyz/target-cmic) | # Credentials Setup Follow the steps below to get the credentials needed to connect CMiC to Hotglue using **OAuth 2.0 Client Credentials**. This guide covers **CMiC Patch 22 or later** only. Official CMiC references: * [OAuth – Client Credential Flow with CMiC](https://docs.cmicglobal.com/portal/Content/E_Reference_Material/OAuth/References/OAuth_Client_credentials_flow_CMiC.htm) * [OAuth – Overview with CMiC](https://docs.cmicglobal.com/portal2/Content/CMiC_Assist/SYS_OAUTH/Reference/SYS_OAUTH_Overview_with_CMiC.htm) Complete Microsoft Entra first, then finish everything in CMiC. 1. [Register an app in Microsoft Entra ID](#1-register-an-app-in-microsoft-entra-id) 2. [Create a service user in CMiC](#2-create-a-service-user-in-cmic) 3. [Register the app in CMiC API Security](#3-register-the-app-in-cmic-api-security) You need: * Admin access to **Microsoft Entra ID** (Azure AD) * Admin access to **CMiC** *** ## 1. Register an app in Microsoft Entra ID 1. Sign in to the [Azure Portal](https://portal.azure.com). 2. Open **Microsoft Entra ID**. 3. On the Overview page, click **+ Add** → **App registration**. 4. Enter a name (for this example, we used `cmic-oauth2`). 5. Under **Supported account types**, select **Single tenant** (your organization only). 6. Under **Redirect URI**, choose **Web** and enter: ```text theme={null} /oauth/callback ``` Use your environment’s **Web App URL** from the table below. | Environment | Web App URL (Redirect URI host) | | :- | :- | | Atlas Prod | [https://atlas.cmiccloud.com](https://atlas.cmiccloud.com) | | Atlas Test | [https://atlas-test.cmiccloud.com](https://atlas-test.cmiccloud.com) | | Nova Prod | [https://nova.cmiccloud.com](https://nova.cmiccloud.com) | | Nova Test | [https://nova-test.cmiccloud.com](https://nova-test.cmiccloud.com) | | Partner Sandbox | [https://partner-sandbox.cmiccloud.com](https://partner-sandbox.cmiccloud.com) | Source: [Cloud Web APP and API URLs](https://developers.cmicglobal.com/v1/docs/cloud-api-server-urls). 7. Click **Register**. ### Copy your IDs After registration, you land on the app **Overview** page: ![Microsoft Entra app Overview page after registration. Copy Application (client) ID and Directory (tenant) ID from Essentials.](https://mintcdn.com/hotglue/LXUlxj9KgwFwdd8X/connectors/images/cmic/entra-app-overview.png?fit=max\&auto=format\&n=LXUlxj9KgwFwdd8X\&q=85\&s=e85137274bb281931dfca7d6d0a138ac) Copy and save these two values from **Essentials**: * **Application (client) ID** — this is your **Client ID** * **Directory (tenant) ID** — this is your **Tenant ID** ### Create a client secret 1. On the app **Overview** page, under **Essentials**, click **Client credentials**. 2. This opens **Certificates & secrets**. Open the **Client secrets** tab. 3. Click **New client secret**. 4. Add a description, choose an expiry, and click **Add**. 5. Copy the secret **Value** right away (you will not see it again). This is your **Client Secret**. You are done in Entra. Keep the **Client ID**, **Tenant ID**, and **Client Secret** for the next steps. *** ## 2. Create a service user in CMiC Create a dedicated CMiC user for this integration (not a person’s everyday login). Official CMiC guide: [System Data – Create New User for Cloud](https://docs.cmicglobal.com/portal2/Content/CMiC_Assist/SYS_SD/How_To/SYS_SD_Create_New_User_Cloud.htm). 1. Sign in to your CMiC web app. 2. Go to **System Data** → **Security** → **Users** → **User Maintenance**. 3. Click **Create New User**. This opens the **User Setup** page: ![CMiC User Setup page with User Profile and Security sections.](https://mintcdn.com/hotglue/LXUlxj9KgwFwdd8X/connectors/images/cmic/cmic-user-setup.png?fit=max\&auto=format\&n=LXUlxj9KgwFwdd8X\&q=85\&s=cf8dd513ee12b70b20ebd4ba75bcb5e2) 4. Fill in the **User Profile** fields. Example: | Field | Example | | - | - | | **Existing Contact** | On (toggle label becomes **New Contact** when enabled) | | **External User** | On (toggle label becomes **Internal User** when enabled) | | **Username** | Choose a service username | | **First Name / Last Name** | Choose a first and last name for this service user | | **Email Address** | Use an email your team monitors | | **Partner** | Click the magnifying glass and select your company | | **Contact** | Fills in automatically after you select the company | | **LDAP Name** | `Default` | | **Financials Console** | Optional — for example, your default Financials console | | **xProjects Console** | Optional — for example, your default xProjects console | 5. Under **Security**, assign the roles this service user needs (or copy them from a similar access user). 6. Click **Create**. 7. On **Finish Setup**, follow the steps shown, then click **Ok**. 8. Check the confirmation email sent to the address you entered, and follow the steps there to finish setting up the user. *** ## 3. Register the app in CMiC API Security 1. In CMiC, go to **System Data** → **API Management** → **Setup** → **API Security**. 2. At the top of the page, open the **App Registration** step. 3. Click **Insert** and fill in: | Field | What to enter | | - | - | | **Description** | For example, `Hotglue OAuth` | | **Application ID** | **Client ID** | | **Issuer URL** | `https://sts.windows.net//` (include the trailing `/`) | | **JSON Web Keyset URL** | `https://login.microsoftonline.com//discovery/v2.0/keys` | | **Service User** | The service user from step 2 | | **System Defined** | Unchecked | | **GCS** | Unchecked | | **Auth URL** | `https://login.microsoftonline.com//oauth2/v2.0/authorize` | | **Token URL** | `https://login.microsoftonline.com//oauth2/v2.0/token` | | **Scope** | `api:///.default` | 4. Click **Save**. ## Checklist * [ ] Entra app registered * [ ] **Client ID**, **Client Secret**, and **Tenant ID** stored * [ ] CMiC service user created * [ ] CMiC App Registration saved # Confluence Source: https://docs.hotglue.com/connectors/confluence # Connector Details | Name | Value | | :- | :- | | Platform | [Confluence](https://atlassian.com/software/confluence) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/edgarrmondragon/tap-confluence](https://github.com/edgarrmondragon/tap-confluence) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # ConnectWise Source: https://docs.hotglue.com/connectors/connectwise # Connector Details | Name | Value | | :- | :- | | Platform | [ConnectWise](https://connectwise.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/chauncywilson/tap-connectwise](https://gitlab.com/chauncywilson/tap-connectwise) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Constrafor Source: https://docs.hotglue.com/connectors/constrafor # Connector Details | Name | Value | | :- | :- | | Tap Repo | [https://github.com/hotgluexyz/tap-constrafor](https://github.com/hotgluexyz/tap-constrafor) | | Tap Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Contentful Source: https://docs.hotglue.com/connectors/contentful # Connector Details | Name | Value | | :- | :- | | Platform | [Contentful](https://contentful.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-contentful](https://gitlab.com/hotglue/tap-contentful) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Contentful connector. The first thing that you need to do to get your Contentful credentials is to head to your [Contentful account](https://be.contentful.com/login). Make sure that you go ahead and sign into Contentful. If you do not have a Contentful account, you can create one for free. ![](https://files.readme.io/72b9e73-Screen_Shot_2022-04-04_at_2.38.54_PM.png "Screen Shot 2022-04-04 at 2.38.54 PM.png") Once you're logged in to Contentful, head to the Settings option on the top of the page. ![](https://files.readme.io/f9d0191-Screen_Shot_2022-04-04_at_3.25.48_PM.png "Screen Shot 2022-04-04 at 3.25.48 PM.png") From the resulting drop down, select the API Keys option. ![](https://files.readme.io/6d98eaf-Screen_Shot_2022-04-04_at_3.27.48_PM.png "Screen Shot 2022-04-04 at 3.27.48 PM.png") On this page, go ahead and select the Content management tokens. ![](https://files.readme.io/279e8eb-Screen_Shot_2022-04-04_at_3.28.47_PM.png "Screen Shot 2022-04-04 at 3.28.47 PM.png") On this page, go ahead and select the "Generate personal token" button. ![](https://files.readme.io/3e24447-Screen_Shot_2022-04-04_at_3.29.35_PM.png "Screen Shot 2022-04-04 at 3.29.35 PM.png") Now go ahead and name your token something similar to "hotglue token" and then click generate. ![](https://files.readme.io/32e6bb6-Screen_Shot_2022-04-04_at_3.32.45_PM.png "Screen Shot 2022-04-04 at 3.32.45 PM.png") You now have your Contentful access token! The next step is to get your Space ID. It is pretty simple. ![](https://files.readme.io/e00059a-Screen_Shot_2022-04-04_at_3.34.34_PM.png "Screen Shot 2022-04-04 at 3.34.34 PM.png") Your Space ID should be in the URL of your Contentful environment. Go ahead and grab it and paste it into hotglue. You now have your Contentful credentials! # Copper Source: https://docs.hotglue.com/connectors/copper # Connector Details | Name | Value | | :- | :- | | Platform | [Copper](https://copper.com) | | Auth Type | API Keys | | Direction | Read | | Triggers | Supported (1 triggers available by default) | | Tap Repo | [https://gitlab.com/hotglue/tap-copper](https://gitlab.com/hotglue/tap-copper) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Databricks Source: https://docs.hotglue.com/connectors/databricks # Connector Details | Name | Value | | :- | :- | | Platform | [Databricks](https://databricks.com) | | Auth Type | OAuth | | Direction | Write | | Target Repo | [https://github.com/hotgluexyz/target-databricks](https://github.com/hotgluexyz/target-databricks) | | Target Metrics | Usage: (medium) | # Credentials Setup: Personal Access Token (PAT) or OAuth (recommend) ## PAT Configuration Go to the [Databricks Website](https://www.databricks.com/) and sign-in\ Click on your user account image on the top right of the screen\ Go to `Settings`\ Go to `User -> Developer`\ Under `Access Tokens`, click on `Manage`\ Then click on `Generate new Token`\ Add a `Comment` for this token, set a life time and under API Scopes select `sql` ![New PAT Modal](https://mintcdn.com/hotglue/E7a9dZNwew8vk0d_/connectors/images/databricks/new-pat-modal.png?fit=max\&auto=format\&n=E7a9dZNwew8vk0d_\&q=85\&s=94622a9b7826973420cc0323fdfa762b) Click on `Generate`\ Copy the newly generated token and use it in the hotglue target configuration ## OAuth Configuration Note: this authentication method is not avaible on Databricks free edition. Follow the steps below to register the "OAuth App" you need to use the Databricks connector. This is a one-time process to create your OAuth app. Once you add your app credentials to hotglue, your client will just need to login to their Databricks account. Go to the [Databricks Accounts Console](https://accounts.cloud.databricks.com/)\ On the left menu click on `Settings`\ Then click on the `App Connections` tab\ Click on `Add Connection`\ Enter an application name (example: `HG Test`)\ In Redirect URLs enter `https://hotglue.xyz/callback`\ In `Access Scopes` select `SQL` ![New OAuth App settings](https://mintcdn.com/hotglue/E7a9dZNwew8vk0d_/connectors/images/databricks/add-oauth-app.png?fit=max\&auto=format\&n=E7a9dZNwew8vk0d_\&q=85\&s=7e4e1e9f39726314d5d608ffd72ae31c) Click `Add`\ You will be shown a modal with the Client ID and Client Secret. Copy both values, you'll use it in the hotglue target configuration ![OAuth Client ID and Client Secret](https://mintcdn.com/hotglue/E7a9dZNwew8vk0d_/connectors/images/databricks/add-oauth-app.png?fit=max\&auto=format\&n=E7a9dZNwew8vk0d_\&q=85\&s=7e4e1e9f39726314d5d608ffd72ae31c) # DearSystems Source: https://docs.hotglue.com/connectors/dearsystems # Connector Details | Name | Value | | :- | :- | | Platform | [DearSystems](https://dearsystems.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-dearsystems](https://gitlab.com/hotglue/tap-dearsystems) | | Tap Metrics | Usage: (medium) Success Rate: (medium) | # Delighted Source: https://docs.hotglue.com/connectors/delighted # Connector Details | Name | Value | | :- | :- | | Platform | [Delighted](https://delighted.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-delighted](https://gitlab.com/hotglue/tap-delighted) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Delighted connector. The first thing you need to do is log in to the [Delighted](https://app.delighted.com/signin) portal. ![](https://files.readme.io/bbf01bb-delighted-01.png "delighted-01.png") Enter the credentials and click on **Sign in** button. ![](https://files.readme.io/607a9aa-delighted-06.png "delighted-06.png") You can then access your API key by clicking the API header at the bottom of page. ![](https://files.readme.io/2c2b9af-delighted-07.png "delighted-07.png") Now you can go ahead and copy the API key into hotglue. # Donorperfect Source: https://docs.hotglue.com/connectors/donorperfect # Connector Details | Name | Value | | :- | :- | | Platform | [DonorPerfect](https://donorperfect.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-donorperfect](https://github.com/hotgluexyz/tap-donorperfect) | | Target Repo | [https://github.com/hotgluexyz/target-donorperfect](https://github.com/hotgluexyz/target-donorperfect) | | Tap Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Target Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Dotykacka Source: https://docs.hotglue.com/connectors/dotykacka # Connector Details | Name | Value | | :- | :- | | Platform | [Dotykacka](https://dotykacka.cz) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-dotykacka](https://gitlab.com/hotglue/tap-dotykacka) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Microsoft Dynamics 365 Source: https://docs.hotglue.com/connectors/dynamics # Connector Details | Name | Value | | :- | :- | | Platform | [Microsoft Dynamics 365](https://dynamics.microsoft.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-dynamics](https://github.com/hotgluexyz/tap-dynamics) | | Target Repo | [https://gitlab.com/hotglue/target-dynamics](https://gitlab.com/hotglue/target-dynamics) | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (low) | | Unified Schema | Supported in [Sales Unified Schema](https://hotglue.com/docs/unified). (Supported tables: Contacts, Companies, Deals, Users) | # Credentials Setup Follow the steps below to get the credentials you need to use the Microsoft Dynamics 365 connector. The first thing that you need to do to get your Microsoft Dynamics 365 CRM OAuth credentials is to [login](https://go.microsoft.com/fwlink/?linkid=2083908) to the Azure portal using an account with administrator permission. If you do not have an Azure account, you can create learn how to create one [here](https://docs.microsoft.com/en-us/office/developer-program/microsoft-365-developer-program). ![](https://files.readme.io/fdce9e9-azure-app-registrations-page.png "azure-app-registrations-page.png") Once in the Azure Portal, select the Azure Active Directory in the left pane and select App registrations and click on New registration. ![](https://files.readme.io/d27a30b-new-app-registration-page.png "new-app-registration-page.png") In the Register an application page, enter your application's registration information! Firstly, in the name Section enter your company's name. Then select Accounts in any organizational directory option from the Supported account types section. Set the Redirect URI to ```text theme={null} https://hotglue.xyz/callback ``` Click on Register to create the application. ![](https://files.readme.io/7d42b5e-app-registration-overview-page.png "app-registration-overview-page.png") On the app Overview page, hover over Application (client) ID value, and select the Copy icon to copy the value as you'll need to specify this in your application's authentication code or app.config file where appropriate. ![](https://files.readme.io/1d6f0cc-app-registration-manifest-page.png "app-registration-manifest-page.png") Select Manifest tab, in the manifest editor, set the allowPublicClient\* property to true and click on Save. ![](https://files.readme.io/7e15d5a-azure-api-permissions-page.png "azure-api-permissions-page.png") Select the API permissions tab and then go ahead and click on the Add a permission button. ![](https://files.readme.io/13387b1-app-registration-select-api-page.png "app-registration-select-api-page.png") Search for and choose Dataverse under the APIs my organization uses tab. If Dataverse is not found, then search for Common Data Service". > 📘 Tip > > If you are presented with more than one Common Data Service item in the search list, choose any one of them. In the next step the service name and URL will be shown. At that point you can go back to the API search and choose a different Dataverse list item if needed. ![](https://files.readme.io/27202c1-app-registration-delegate-permissions-page.png "app-registration-delegate-permissions-page.png") Click on Delegated permissions and check the options and click on Add permissions. This will wrap up registering your app in the Azure Active Directory! Now you can insert the client id and client secret pair into your hotglue Microsoft Dynamics 365 source settings. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.1.6](https://github.com/hotgluexyz/tap-dynamics/releases/tag/v0.1.6) | fixes | > | [v0.1.5](https://github.com/hotgluexyz/tap-dynamics/releases/tag/v0.1.5) | bug fixes | > | [v0.1.3](https://github.com/hotgluexyz/tap-dynamics/releases/tag/v0.1.3) | | > | [](https://github.com/hotgluexyz/tap-dynamics/releases/tag/v0.1.2) | | > | [v0.1.1 - Rename domain field to org](https://github.com/hotgluexyz/tap-dynamics/releases/tag/v0.1.1) | - Renamed `domain` field to `org` - Changed catalog generation to `available` | # Microsoft Dynamics Business Central Source: https://docs.hotglue.com/connectors/dynamics-bc # Connector Details | Name | Value | | :- | :- | | Platform | [Microsoft Dynamics Business Central](https://dynamics.microsoft.com) | | Auth Type | OAuth or Client Credentials | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-dynamics-bc](https://github.com/hotgluexyz/tap-dynamics-bc) | | Target Repo | [https://github.com/hotgluexyz/target-dynamics-bc](https://github.com/hotgluexyz/target-dynamics-bc) | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (medium) | | Unified Schema | Supported in [Accounting Unified Schema](https://hotglue.com/docs/unified). (Supported tables: GeneralLedgerReport) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Credentials Setup There are two separate authentication flows available for the Microsoft Dynamics Business Central connector: * OAuth. * Client Credentials. Use only the section that matches your authentication flow. # OAuth flow ## OAuth flow on Microsoft Entra 1. [Sign in](https://entra.microsoft.com/) to the Microsoft Entra admin center as at least a Cloud Application Administrator. 2. If you have access to multiple tenants, use the Settings icon in the top menu to switch to the tenant in which you want to register the application from the **Directories + subscriptions** menu. 3. Go to **Identity** > **Applications** > **App registrations** and select **New registration**. 4. Enter a display name for your application. Users of your application might see this display name when they connect their Dynamics Business Central account. 5. For **Sign-in audience**, make sure to allow all accounts to use your application. 6. For **Redirect URI**, use `https://hotglue.xyz/callback`. 7. Complete your registration by selecting **Register**. The next step is to enable this app to access Dynamics Business Central: 8. On the left-hand panel, navigate to **Manage** > **API Permissions**. Add the following permissions: * Dynamics 365 Business Central > `Financials.ReadWrite.All` * Dynamics 365 Business Central > `user_impersonation` * Microsoft Graph > `User.Read` The last step in the Microsoft Entra application is to retrieve the Client Id and Client Secret: 9. Select **Overview**. There, you will see the Application (client) ID. You'll need to add this Client Id to Hotglue in future steps. 10. Under **Manage** > **Certificates and Secrets** > **Client Secrets**, add a new client secret. You'll need to add this client secret value to Hotglue in future steps. ## Enabling the OAuth Dynamics Business Central Connector on Hotglue Add the Dynamics Business Central source to a new or existing flow, and add credentials under the source's credentials tab: * `OAuth Client Id`: Use the **Application (client) ID** from your Microsoft Entra app registration. * `OAuth Client Secret`: Use the **client secret value** (not the secret Id) from your Microsoft Entra app. ## Tenant registration with OAuth When your tenants sign into their Dynamics Business Central accounts, they'll need to enter the following information: * `Environment Name`: There is a dedicated section explaining [How to retrieve the Environment Name](#how-to-retrieve-the-environment-name). # Client Credentials flow ## Client Credentials flow on Microsoft Entra This involves the end user creating their own app in Microsoft Entra. Guide them to: 1. [Sign in](https://entra.microsoft.com/) to the Microsoft Entra admin center as at least a Cloud Application Administrator. 2. Go to **Identity** > **Applications** > **App registrations** and select **New registration**. 3. Enter a display **Name** for the application. 4. For **Supported account types**, select **Single tenant only**. 5. Complete the registration by selecting **Register**. The next step is to enable this app to access Dynamics Business Central: 6. On the left-hand panel, navigate to **Manage** > **API Permissions**. Add the following permissions: * Dynamics 365 Business Central > `API.ReadWrite.All` * Dynamics 365 Business Central > `AdminCenter.ReadWrite.All` The last step in the Microsoft Entra application is to retrieve the Client Id and Client Secret: 7. Select **Overview**. There, you will see the Application (client) ID. You'll need to add the Client Id to Hotglue in future steps. 8. Under **Manage** > **Certificates and Secrets** > **Client Secrets**, add a new client secret. You'll need to add the Client Secret value to Hotglue in future steps. ## Client Credentials flow on Microsoft Dynamics Business Central This involves the end user granting access to their Microsoft Entra application in Microsoft Dynamics Business Central. Guide them to: 1. Sign in to [Dynamics 365 Business Central](https://businesscentral.dynamics.com/) with an Administrator account. 2. Use the search icon in the top-right and open **Microsoft Entra Applications**. 3. Select **New**. 4. Configure the app record: * **Client Id**: Paste the Application (client) ID from your Entra app registration. * **Description**: Enter a clear name. * **State**: Set to **Enabled**. 5. Under **User Permission Sets**, add the permissions: * `D365 Basic`. * `D365 FULL ACCESS`. ## Enabling the Client Credentials Dynamics Business Central connector on Hotglue Add the Dynamics BC Client Credentials source to a new or existing flow. No credentials are necessary in this step. ## Tenant registration with Client Credentials When your tenants sign into their Dynamics Business Central accounts, they'll need to enter the following information: * `Environment Name`: There is a dedicated section explaining [How to retrieve the Environment Name](#how-to-retrieve-the-environment-name). * `Tenant Id`: There is a dedicated section explaining [How to retrieve the Tenant Id](#how-to-retrieve-the-tenant-id). * `Client Id`: Use the **Application (client) ID** from the Microsoft Entra application. * `Client Secret`: Use the **client secret value** (not the secret Id) from the Microsoft Entra application. # How to retrieve the Environment Name Your users can find their `Environment Name` by first navigating to the **Settings** tab in Dynamics Business Central: ![DBC Settings Icon](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/DBCFindSettings.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=8cae3b0a0f0a47030f9d928f971e4cef) Then, clicking on **Admin Center**: ![DBC Admin Center](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/DBCFindAdminCenter.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=200d14919a1d924d941ab3357f5bc46f) Finally, they can find all their Business Central environments under **Environments**. ![DBC Env Name](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/DBCFindEnvName.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=220f00556236be6dfb4665139da02124) # How to retrieve the Tenant Id Your users can find their `Tenant Id` by first navigating to the **Settings** tab in Dynamics Business Central: ![DBC Settings Icon](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/DBCFindSettings.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=8cae3b0a0f0a47030f9d928f971e4cef) Then, clicking on **Admin Center**: ![DBC Admin Center](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/DBCFindAdminCenter.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=200d14919a1d924d941ab3357f5bc46f) Finally, they can find their `Tenant Id` in the page URL, such as: `businesscentral.dynamics.com/{TENANT-Id}/admin` ![DBC Admin Center](https://mintcdn.com/hotglue/9TgPaQDd10a3Uzjj/connectors/images/DBCFindTenantId.png?fit=max\&auto=format\&n=9TgPaQDd10a3Uzjj\&q=85\&s=e81afcc2e8c39cba0ea16fdd12f6f4ff) # Microsoft Dynamics 365 Finance Source: https://docs.hotglue.com/connectors/dynamics-finance # Connector Details | Name | Value | | :- | :- | | Platform | [Microsoft Dynamics 365 Finance](https://dynamics.microsoft.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-dynamics-finance](https://gitlab.com/hotglue/tap-dynamics-finance) | | Target Repo | [https://github.com/hotgluexyz/target-dynamics-finance](https://github.com/hotgluexyz/target-dynamics-finance) | | Tap Metrics | Usage: (medium) Success Rate: (high) | | Target Metrics | Usage: (medium) Success Rate: (high) | # Microsoft Dynamics On-Premise Source: https://docs.hotglue.com/connectors/dynamics-onprem # Connector Details | Name | Value | | :- | :- | | Platform | [Microsoft Dynamics On-Premise](https://api) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # ECB Exchange Rates Source: https://docs.hotglue.com/connectors/ecbexchangerates # Connector Details | Name | Value | | :- | :- | | Platform | [ECB Exchange Rates](https://ecb.europa.eu) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-ecbexchangerates](https://gitlab.com/hotglue/tap-ecbexchangerates) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Ecwid Source: https://docs.hotglue.com/connectors/ecwid # Connector Details | Name | Value | | :- | :- | | Platform | [Ecwid](https://ecwid.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-ecwid](https://gitlab.com/hotglue/tap-ecwid) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Etsy Source: https://docs.hotglue.com/connectors/etsy # Connector Details | Name | Value | | :- | :- | | Platform | [Etsy](https://etsy.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-etsy](https://github.com/hotgluexyz/tap-etsy) | | Target Repo | [https://gitlab.com/hotglue/target-etsy](https://gitlab.com/hotglue/target-etsy) | | Tap Metrics | Usage: (high) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (medium) | | Unified Schema | Supported in [Ecommerce Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders) | # Eventbrite Source: https://docs.hotglue.com/connectors/eventbrite # Connector Details | Name | Value | | :- | :- | | Platform | [Eventbrite](https://eventbrite.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-eventbrite](https://gitlab.com/hotglue/tap-eventbrite) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Eventbrite connector. To get your credentials for Eventbrite, you are first going to need to log in to [Eventbrite](https://www.https://www.eventbrite.com/signin/). ![](https://files.readme.io/55b5789-cred-01.png "cred-01.png") Enter the credentials and click on **Log in** button. ![](https://files.readme.io/ee7e9b8-cred-02.png "cred-02.png") Check the registered mail. You will receive the email from eventbrite and click on the login button. ![](https://files.readme.io/a18b1f8-cred-03.png "cred-03.png") You will land on eventtribe home page. ![](https://files.readme.io/cae78db-cred-04.png "cred-04.png") Click on the account name and then Account Settings. ![](https://files.readme.io/fc90202-cred-06.png "cred-06.png") You will land on the Account Information page. Then click on Developer Links on left nav pane and select API Keys ![](https://files.readme.io/48bdbf1-cred-07.png "cred-07.png") Click on the organization's name and you should be able to copy API key into hotglue. You have now gotten your credentials for Eventbrite! # Exact Source: https://docs.hotglue.com/connectors/exact # Connector Details | Name | Value | | :- | :- | | Platform | [Exact](https://exactonline.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-exact](https://github.com/hotgluexyz/tap-exact) | | Target Repo | [https://github.com/hotgluexyz/target-exact](https://github.com/hotgluexyz/target-exact) | | Tap Metrics | Usage: (high) | | Target Metrics | Usage: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Exact connector. The first thing you need to do is log in to Exact, or create a free [Exact account](https://apps.exactonline.com/us/en-US/V2). ![](https://files.readme.io/c76cc3e-image.png) Click on Manage my app. ![](https://files.readme.io/314f11e-image.png) Scroll down you will see production Apps. You can register your app. ![](https://files.readme.io/ab80dcf-image.png) Enter App name and Add redirect URI. You should add the Redirect URI **[https://hotglue.xyz/callback](https://hotglue.xyz/callback)** ![](https://files.readme.io/62f0c50-image.png) You can get Client ID and secret from **Develop Your APP** section. Now you can insert the client id and client secret pair into your hotglue Exact source settings. # Excel Source: https://docs.hotglue.com/connectors/excel # Connector Details | Name | Value | | :- | :- | | Platform | [Excel](https://office.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-excel](https://gitlab.com/hotglue/tap-excel) | | Target Repo | [https://gitlab.com/hotglue/target-excel](https://gitlab.com/hotglue/target-excel) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Facebook Ads Source: https://docs.hotglue.com/connectors/facebook # Connector Details | Name | Value | | :- | :- | | Platform | [Facebook Ads](https://facebook.com/business/ads) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-facebook](https://github.com/hotgluexyz/tap-facebook) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Facebook Ads connector. To get your credentials for Facebook Ads, you are first going to need to log in to [Facebook](https://developers.facebook.com/docs/facebook-login/). ![](https://files.readme.io/9c24f1d-facebook_login_01.png "facebook_login_01.png") Click on **Log in** button. ![](https://files.readme.io/cb63835-facebook_login_02.png "facebook_login_02.png") Enter your credentials and Log In. ![](https://files.readme.io/86ac61c-facebook-01.png "facebook-01.png") Click on create APP button. ![](https://files.readme.io/9028f14-facebook-06.png "facebook-06.png") elect **Business** type app and Click on \*\*Next \*\*button. ![](https://files.readme.io/16484f8-facebook-04.png "facebook-04.png") Fill the Basic Information Form and Click on **Create app** button. ![](https://files.readme.io/01292c3-facebook-05.png "facebook-05.png") A pop-out will appear. Enter your facebook password. ![](https://files.readme.io/8704817-facebook_login_03.png "facebook_login_03.png") Dashboard will appear once app is successfully added. ![](https://files.readme.io/9c034d4-facebook_login_04.png "facebook_login_04.png") In the menu at the left corner, click on the “Facebook Login” link to expand the sub-menu. Next, you need to click on “Settings” from the sub-menu. ![](https://files.readme.io/3b6fb8f-facebook_login_05.png "facebook_login_05.png") Next, you need to Click on “Settings” from the sub-menu. ![](https://files.readme.io/2a667bb-facebook_login_06.png "facebook_login_06.png") Now, you will see the details where you have to enter your website URL in “Valid OAuth redirect URIs”. For example, I entered `https://hotglue.xyz/callback`. ![](https://files.readme.io/e3b9162-facebook_login_07.png "facebook_login_07.png") Now expand the Setting menu and select Basic. Here you can find the App ID and App Secret. Then click on the “Show” button in the “App Secret” text box. You can copy the “App Id” and “App Secret” copy the credentials into hotglue. You have now gotten your credentials for Facebooks Ads! # Faire Source: https://docs.hotglue.com/connectors/faire # Connector Details | Name | Value | | :- | :- | | Platform | [Faire](https://faire.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-faire](https://gitlab.com/hotglue/tap-faire) | | Tap Metrics | Usage: (high) Success Rate: (high) | | Unified Schema | Supported in [Ecommerce Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders, Products) | # Files Source: https://docs.hotglue.com/connectors/file # Connector Details | Name | Value | | :- | :- | | Platform | [Files](https://file) | | Auth Type | API Keys | | Direction | Read | | Tap Metrics | Usage: (high) Success Rate: (high) | # Firebase Auth Source: https://docs.hotglue.com/connectors/firebase-auth # Connector Details | Name | Value | | :- | :- | | Platform | [Firebase Auth](https://firebase.google.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-firebase-auth](https://gitlab.com/hotglue/tap-firebase-auth) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Firestore Source: https://docs.hotglue.com/connectors/firestore # Connector Details | Name | Value | | :- | :- | | Platform | [Firestore](https://firebase.google.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-firestore](https://gitlab.com/hotglue/tap-firestore) | | Target Repo | [https://gitlab.com/hotglue/target-firestore](https://gitlab.com/hotglue/target-firestore) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Fishbowl Inventory Source: https://docs.hotglue.com/connectors/fishbowl # Connector Details | Name | Value | | :- | :- | | Platform | [Fishbowl Inventory](https://fishbowl.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-fishbowl](https://gitlab.com/hotglue/tap-fishbowl) | | Target Repo | [https://gitlab.com/hotglue/target-fishbowl](https://gitlab.com/hotglue/target-fishbowl) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Fixer.io Source: https://docs.hotglue.com/connectors/fixerio # Connector Details | Name | Value | | :- | :- | | Platform | [Fixer.io](https://fixer.io) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-fixerio](https://gitlab.com/hotglue/tap-fixerio) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Follow Up Boss Source: https://docs.hotglue.com/connectors/followupboss # Connector Details | Name | Value | | :- | :- | | Platform | [Follow Up Boss](https://followupboss.com) | | Auth Type | API Keys | | Direction | Read | | Triggers | Supported (1 triggers available by default) | | Tap Repo | [https://gitlab.com/hotglue/tap-followupboss](https://gitlab.com/hotglue/tap-followupboss) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Fortnox Source: https://docs.hotglue.com/connectors/fortnox # Connector Details | Name | Value | | :- | :- | | Platform | [Fortnox](https://fortnox.se) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-fortnox](https://gitlab.com/hotglue/tap-fortnox) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # FreshBooks Source: https://docs.hotglue.com/connectors/freshbooks # Connector Details | Name | Value | | :- | :- | | Platform | [FreshBooks](https://freshbooks.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-freshbooks](https://gitlab.com/hotglue/tap-freshbooks) | | Target Repo | [https://github.com/hotgluexyz/target-freshbooks](https://github.com/hotgluexyz/target-freshbooks) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Freshcaller Source: https://docs.hotglue.com/connectors/freshcaller # Connector Details | Name | Value | | :- | :- | | Platform | [Freshcaller](https://freshcaller.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-freshcaller](https://gitlab.com/hotglue/tap-freshcaller) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Freshcaller connector. o get your credentials for FreshCaller, you are first going to need to log in to [FreshCaller](https://www.freshworks.com/freshcaller-cloud-pbx/). ![](https://files.readme.io/11d891b-fresh-caller-01.png "fresh-caller-01.png") Enter account name and click on **Proceed** button. ![](https://files.readme.io/9e2aeec-fresh-caller-03.png "fresh-caller-03.png") Enter the credentials and sign in. ![](https://files.readme.io/23c4e9c-fresh-caller-05.png "fresh-caller-05.png") Dashboard will be shown. Click on Username and select **Profile Settings**. ![](https://files.readme.io/f4a77da-fresh-caller-06.png "fresh-caller-06.png") # Freshdesk Source: https://docs.hotglue.com/connectors/freshdesk # Connector Details | Name | Value | | :- | :- | | Platform | [Freshdesk](https://freshdesk.io) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-freshdesk](https://github.com/hotgluexyz/tap-freshdesk) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Freshsales Classic Source: https://docs.hotglue.com/connectors/freshsales # Connector Details | Name | Value | | :- | :- | | Platform | [Freshsales Classic](https://freshsales.io) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-freshsales](https://gitlab.com/hotglue/tap-freshsales) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Freshsales Classic connector. The first thing you need to do is log in to [Freshsales](https://www.freshworks.com/crm/login/). ![](https://files.readme.io/660547f-Screen_Shot_2022-03-09_at_5.54.18_PM.png "Screen Shot 2022-03-09 at 5.54.18 PM.png") Your home page should look something like this. On the top of your screen in the URL, you will see your organization name. It will follow the format of "**ORGANIZATION NAME**.myfreshworks.com/crm/sales". Go ahead and input the Organization Name into hotglue. ## API Key ![](https://files.readme.io/3d41674-Screen_Shot_2022-03-09_at_6.00.25_PM.png "Screen Shot 2022-03-09 at 6.00.25 PM.png") Now you need to find the API Key, go ahead and click on the personal icon in the top right hand corner. ![](https://files.readme.io/ce5e203-Screen_Shot_2022-03-09_at_7.56.13_PM.png "Screen Shot 2022-03-09 at 7.56.13 PM.png") From the resulting drop down, select the Settings page. ![](https://files.readme.io/71fab55-Screen_Shot_2022-03-09_at_7.57.35_PM.png "Screen Shot 2022-03-09 at 7.57.35 PM.png") Now that you are on your Personal Settings page, head to the API Settings tab. ![](https://files.readme.io/3d9e1d4-Screen_Shot_2022-03-09_at_7.59.01_PM.png "Screen Shot 2022-03-09 at 7.59.01 PM.png") And here you have your Freshsales API Key! Go ahead and copy it into hotglue. # Freshsales Suite Source: https://docs.hotglue.com/connectors/freshworks # Connector Details | Name | Value | | :- | :- | | Platform | [Freshsales Suite](https://freshworks.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-freshworks](https://gitlab.com/hotglue/tap-freshworks) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Freshsales Suite connector. ## Organization Name The first thing you need to do is log in to [Freshworks CRM](https://www.freshworks.com/crm/login/). ![](https://files.readme.io/81286f2-freshwork-01.png "freshwork-01.png") Your home page should look something like this. On the top of your screen in the URL, you will see your organization name. It will follow the format of "**ORGANIZATION NAME**.myfreshworks.com/crm/sales". Go ahead and input the Organization Name into hotglue. ## API Key ![](https://files.readme.io/3d41674-Screen_Shot_2022-03-09_at_6.00.25_PM.png "Screen Shot 2022-03-09 at 6.00.25 PM.png") Now you need to find the API Key, go ahead and click on the personal icon in the top right hand corner. ![](https://files.readme.io/ce5e203-Screen_Shot_2022-03-09_at_7.56.13_PM.png "Screen Shot 2022-03-09 at 7.56.13 PM.png") From the resulting drop down, select the Settings page. ![](https://files.readme.io/71fab55-Screen_Shot_2022-03-09_at_7.57.35_PM.png "Screen Shot 2022-03-09 at 7.57.35 PM.png") Now that you are on your Personal Settings page, head to the API Settings tab. ![](https://files.readme.io/3d9e1d4-Screen_Shot_2022-03-09_at_7.59.01_PM.png "Screen Shot 2022-03-09 at 7.59.01 PM.png") And here you have your Freshworks API CRM Key! Go ahead and copy it into hotglue. # Front Source: https://docs.hotglue.com/connectors/frontapp # Connector Details | Name | Value | | :- | :- | | Platform | [Front](https://frontapp.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-frontapp](https://gitlab.com/hotglue/tap-frontapp) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # FTP Source: https://docs.hotglue.com/connectors/ftp # Connector Details | Name | Value | | :- | :- | | Platform | [FTP](https://ftp) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-ftp](https://gitlab.com/hotglue/tap-ftp) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Fulfil Source: https://docs.hotglue.com/connectors/fulfil # Connector Details | Name | Value | | :- | :- | | Platform | [Fulfil](https://fulfil.io) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-fulfil](https://gitlab.com/hotglue/tap-fulfil) | | Target Repo | [https://gitlab.com/hotglue/target-fulfil](https://gitlab.com/hotglue/target-fulfil) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Fulfil connector. If you need to figure out how to access the necessary Fulfil credentials, head [here](https://developers.fulfil.io/) for a detailed walkthrough. # Gambio Source: https://docs.hotglue.com/connectors/gambio # Connector Details | Name | Value | | :- | :- | | Platform | [Gambio](https://gambio.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-gambio](https://gitlab.com/hotglue/tap-gambio) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # GitHub Source: https://docs.hotglue.com/connectors/github # Connector Details | Name | Value | | :- | :- | | Platform | [GitHub](https://github.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-github](https://github.com/hotgluexyz/tap-github) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the GitHub connector. If you need to find your GitHub Access Token, you have come to the right place. The first thing you need to do is [log in to GitHub](https://github.com/login). ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRejbo0ptUyNzMaCE0%2F-MgRhUeCzAtVp_D60H7A%2FScreen%20Shot%202021-08-06%20at%202.23.04%20PM.png?alt=media\&token=b34b1ccb-a3f5-47cf-9529-fd9e9370fbe9) Now that you are logged in to GitHub, go click on your profile in the top right corner of the page. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRejbo0ptUyNzMaCE0%2F-MgRhkeD-3Gvu4qTPUZs%2FScreen%20Shot%202021-08-06%20at%202.25.22%20PM.png?alt=media\&token=60e44f77-2b67-46d2-b03c-d99fe64e71c7) From the resulting drop down, select the Settings option. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRejbo0ptUyNzMaCE0%2F-MgRi30nRD3UYzzpDikk%2FScreen%20Shot%202021-08-06%20at%202.26.44%20PM.png?alt=media\&token=e4756e5c-d161-4b19-9e32-adfa9ea8a401) This is your settings page. On the right hand side, near the bottom of the page, you should see an option to head to the Developer Settings section of your account. Go ahead and do that. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRejbo0ptUyNzMaCE0%2F-MgRiKRK1Y50q4dqkBck%2FScreen%20Shot%202021-08-06%20at%202.28.07%20PM.png?alt=media\&token=f360ac49-d915-4350-8eaa-064e72983f14) You will now be on this page. Once again, one the left hand side you have a few options. You should select the Personal access tokens tab. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRiTqTMmmInRg-sHJM%2F-MgRio0lGw7yQFKT_3Sb%2FScreen%20Shot%202021-08-06%20at%202.30.07%20PM.png?alt=media\&token=fe6b4517-5e16-4b86-a2ae-f3e6a54489ad) Next, you should click the Generate new token button in the top right hand corner. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRjpchLiV3_s7NUowp%2F-MgRjvx8LSfN9d5IvzHE%2FScreen%20Shot%202021-08-06%20at%202.35.14%20PM.png?alt=media\&token=235d33e5-6795-4e7b-a605-af1def81d5d0) In the Note section write "hotglue." ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRjpchLiV3_s7NUowp%2F-MgRkAnnaT-REhBJN1Oi%2FScreen%20Shot%202021-08-06%20at%202.36.01%20PM.png?alt=media\&token=218c1a29-18c9-45dc-89ee-27969343324b) For the Expiration of your token, you can put whatever you like, as long as you remember to generate a new token and put it in hotglue whenever your old token expires. For this examples sake, I will be setting mine to No expiration. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRjpchLiV3_s7NUowp%2F-MgRkhlqdm8WP17W6X2n%2FScreen%20Shot%202021-08-06%20at%202.38.49%20PM.png?alt=media\&token=09df034d-c84c-42c9-bf18-ff6686ed6e23) For the Scopes, make sure you enable the necessary scopes for hotglue to grab data from GitHub. If you need help figuring out what scopes you should enable, you can chat with us using our live chat feature in hotglue or shoot us an email at [support@hotglue.xyz](mailto:support@hotglue.xyz). ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRkkO-bO5TK-2bXmNT%2F-MgRl66WaqkOSu3KeXdM%2FScreen%20Shot%202021-08-06%20at%202.40.14%20PM.png?alt=media\&token=7eb51a8c-251b-44e6-b48e-c6f60914f4db) Once you have everything configured, go ahead and click the Generate token button. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRkkO-bO5TK-2bXmNT%2F-MgRlNxvvyLHse6JquzW%2FScreen%20Shot%202021-08-06%20at%202.41.32%20PM.png?alt=media\&token=4a5f3fad-ad76-4bb7-a78d-1547257fbb97) You have now created your Personal access token! Make sure to copy it into a safe place as well as copy it into hotglue. Once you do that, you are all set! # GitLab Source: https://docs.hotglue.com/connectors/gitlab # Connector Details | Name | Value | | :- | :- | | Platform | [GitLab](https://gitlab.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-gitlab](https://gitlab.com/hotglue/tap-gitlab) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the GitLab connector. The first thing you must do is log in to your Gitlab account. If you have a Gitlab account, you can [login here](https://gitlab.com/users/sign_in?__cf_chl_jschl_tk__=MuF9GC0ejtTkFz20goTlkDJ.UzN8vbZBMo.6VsObMjw-1639681161-0-gaNycGzNCiU). If you do not have an account, you can create one [here](https://about.gitlab.com/pricing/). ## Gitlab API URL Usually, you Gitlab API URL will be `https://gitlab.com/api/v4` ## Access Token ![](https://files.readme.io/69a5960-Screen_Shot_2021-12-16_at_2.22.37_PM.png "Screen Shot 2021-12-16 at 2.22.37 PM.png") Now that you have logged in to Gitlab, your home page should look something like this. Go ahead to the top right corner and click the circular icon. ![](https://files.readme.io/5e1fb41-Screen_Shot_2021-12-16_at_2.26.27_PM.png "Screen Shot 2021-12-16 at 2.26.27 PM.png") From the resulting drop down, you should click the **Edit Profile** option. ![](https://files.readme.io/641f83c-Screen_Shot_2021-12-16_at_2.43.47_PM.png "Screen Shot 2021-12-16 at 2.43.47 PM.png") From this page, you should go ahead and select the **Access Tokens** tab. ![](https://files.readme.io/7323c80-Screen_Shot_2021-12-16_at_2.52.35_PM.png "Screen Shot 2021-12-16 at 2.52.35 PM.png") You should now be on a page where you can create your own access token. Go ahead and title your access token "hotglue" and give it an expiration date. Now we need to set the scopes for the access token. The gitlab tap expects the following scopes: * `read_user` * `read_api` * `read_repository` * `read_registry` Once you are done selecting your scopes, go ahead and click the **Create personal access token**. ![](https://files.readme.io/30603ab-Screen_Shot_2021-12-16_at_3.11.03_PM.png "Screen Shot 2021-12-16 at 3.11.03 PM.png") You now have your personal access token! Go ahead and copy it into hotglue. ## Your Groups (Optional) ![](https://files.readme.io/c383391-Screen_Shot_2021-12-16_at_3.17.39_PM.png "Screen Shot 2021-12-16 at 3.17.39 PM.png") To find your groups, head to **Menu** option on the top left of the page. ![](https://files.readme.io/4abcdba-Screen_Shot_2021-12-16_at_3.18.29_PM.png "Screen Shot 2021-12-16 at 3.18.29 PM.png") Then, you should navigate to the Groups tab, and within the Groups tab, head to the Your groups tab. ![](https://files.readme.io/67bfb86-Screen_Shot_2021-12-16_at_3.25.27_PM.png "Screen Shot 2021-12-16 at 3.25.27 PM.png") I have a test group here titled **myawesometestgroup**. So in hotglue, I will put myawesometestgroup in the Groups entry. ## Your Projects ![](https://files.readme.io/8c44cdf-Screen_Shot_2021-12-16_at_3.30.43_PM.png "Screen Shot 2021-12-16 at 3.30.43 PM.png") Using the menu, head to the Projects tab. You should then navigate to the Your projects. ![](https://files.readme.io/bdf9ae9-Screen_Shot_2021-12-16_at_3.37.19_PM.png "Screen Shot 2021-12-16 at 3.37.19 PM.png") As you can see, I have a test project. In hotglue, I would input **myorg/myawesomeproject** into hotglue. # Gladly Source: https://docs.hotglue.com/connectors/gladly # Connector Details | Name | Value | | :- | :- | | Platform | [Gladly](https://gladly.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-gladly](https://gitlab.com/hotglue/tap-gladly) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Gmail Source: https://docs.hotglue.com/connectors/gmail # Connector Details | Name | Value | | :- | :- | | Platform | [Gmail](https://gmail.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-gmail](https://github.com/hotgluexyz/tap-gmail) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # GoCardless Source: https://docs.hotglue.com/connectors/gocardless # Connector Details | Name | Value | | :- | :- | | Platform | [GoCardless](https://gocardless.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-gocardless](https://github.com/hotgluexyz/tap-gocardless) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # GoHighLevel Source: https://docs.hotglue.com/connectors/gohighlevel # Connector Details | Name | Value | | :- | :- | | Platform | [GoHighLevel](https://gohighlevel.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-gohighlevel](https://gitlab.com/hotglue/tap-gohighlevel) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Gong Source: https://docs.hotglue.com/connectors/gong # Connector Details | Name | Value | | :- | :- | | Platform | [Gong](https://gong.io) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-gong](https://github.com/hotgluexyz/tap-gong) | | Target Repo | [https://gitlab.com/hotglue/target-gong](https://gitlab.com/hotglue/target-gong) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Gong connector. The first thing you need to do is log in to the [Gong Developer hub](https://app.gong.io/developer-hub). ![](https://files.readme.io/3dac647-gong-01.png "gong-01.png") Enter your email id and click on **Sign in** button. ![](https://files.readme.io/c9073ad-gong-02.png "gong-02.png") Enter your password and Sign in button. ![](https://files.readme.io/75286b2-gong-03.png "gong-03.png") You will land on Dev page. Click on Manage APPS. ![](https://files.readme.io/b7ea9a2-gong-04.png "gong-04.png") You can get API documentation from this page. Click on Create Integration button. ![](https://files.readme.io/d687238-gong-05.png "gong-05.png") Fill the details of your company. You should add the Redirect URI `https://hotglue.xyz/callback`. Scroll down to save the details after filling out the form. ![](https://files.readme.io/c8a915c-gong-06.png "gong-06.png") Once you are done, you can also get your Client ID and Client Secret. Now you can go ahead and copy the credentials into hotglue. # Google Analytics 4 Source: https://docs.hotglue.com/connectors/google-analytics # Connector Details | Name | Value | | :- | :- | | Platform | [Google Analytics 4](https://analytics.google.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-google-analytics-v2](https://github.com/hotgluexyz/tap-google-analytics-v2) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Google Drive Source: https://docs.hotglue.com/connectors/google-drive # Connector Details | Name | Value | | :- | :- | | Platform | [Google Drive](https://drive.google.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-google-drive](https://github.com/hotgluexyz/tap-google-drive) | | Tap Metrics | Usage: (low) | # Setting up the Google Drive File Picker integration ## Create a Google Cloud Project To use the Google Drive connector, first [create a Google Cloud Console project](https://console.cloud.google.com/projectcreate) and ![](https://mintcdn.com/hotglue/9lYhXJtLxmXXxTjD/connectors/images/GDriveCreateProject.png?fit=max\&auto=format\&n=9lYhXJtLxmXXxTjD\&q=85\&s=5111424c9e55694ff898f2daad823130) Create a project at [https://console.cloud.google.com/projectcreate](https://console.cloud.google.com/projectcreate) ## Enable the Google Picker API Next navigate to the **Enabled APIs & Services** menu: ![](https://mintcdn.com/hotglue/9lYhXJtLxmXXxTjD/connectors/images/GDriveEnabledAPIs.png?fit=max\&auto=format\&n=9lYhXJtLxmXXxTjD\&q=85\&s=19f05770bfe3a30c2ddc25060cf90b0b) Press **+ Enable APIs & Services** and enable the `Google Picker` API. This allows your OAuth application to download files that your tenant explicitly gives you access to. ## Creating an OAuth application Next, navigate to the [Google Auth Platform](https://console.cloud.google.com/auth/overview) to create your OAuth application. ![](https://mintcdn.com/hotglue/9lYhXJtLxmXXxTjD/connectors/images/GoogleOAuthApp.png?fit=max\&auto=format\&n=9lYhXJtLxmXXxTjD\&q=85\&s=c44cc83597d1d7cbcf7d8277272fe6e8) Create an external application with the support emails that you would like to surface to your tenants. Next create an OAuth client with the callback `https://hotglue.xyz/callback`: ![](https://mintcdn.com/hotglue/9lYhXJtLxmXXxTjD/connectors/images/CreateGoogleClientID.png?fit=max\&auto=format\&n=9lYhXJtLxmXXxTjD\&q=85\&s=5b00c64600449a110a011a3f1f1e286f) Make sure to copy your client id and secret to be later used in the hotglue dashboard. Finally, navigate to the **Audience** tab to publish your application. Note that until the application is verified by google, your tenants will see a warning before authenticating. ## Generating a client side developer token In order to use Google's client-side file picker, you'll need to generate a developer token for the hotglue widget to use. On the lefthand sidebar, navigate to **APIs & Services > Credentials**. Next press **+ Create Credentials** > **API key** to get an API key. Once its generated, we recommend restricted its scope to just the Google Picker API. ## Getting your App ID Finally, in order to support the Google Picker API, hotglue requires your Google Cloud project number (AKA `app id`). You can find the file picker by navigating to the hot dog icon in the top right corner and pressing project settings. ## Configuring Google Drive connector in hotglue ### Authorization URL The proper authorization url for the Google Picker API is: ``` "https://accounts.google.com/o/oauth2/v2/auth?scope=https%3A//www.googleapis.com/auth/drive.file&access_type=offline&prompt=consent&include_granted_scopes=true&response_type=code" ``` If using Google Drive in a unidirectional (v1) flow, you can configure this by adding the following to your Google Drive [availableSource](/key-concepts/connectors/v1-sources/management): ```json theme={null} "tap_url": "https://accounts.google.com/o/oauth2/v2/auth?scope=https%3A//www.googleapis.com/auth/drive.file&access_type=offline&prompt=consent&include_granted_scopes=true&response_type=code" ``` If using Google Drive in a bidirectional (v2) flow, you can add the following to your [availableConnector](/key-concepts/connectors/v2-connectors/management): ```json theme={null} "auth_url": "https://accounts.google.com/o/oauth2/v2/auth?scope=https%3A//www.googleapis.com/auth/drive.file&access_type=offline&prompt=consent&include_granted_scopes=true&response_type=code" ``` ### Configuring your Google Console application for the widget To support using the Google Picker API in the widget, you can add the following to your availableSource or availableConnector: ```json theme={null} "google_tokens": { "app_id": "", "api_key": "" }, ``` # Google Play Source: https://docs.hotglue.com/connectors/google-play # Connector Details | Name | Value | | :- | :- | | Platform | [Google Play](https://play.google.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-google-play](https://gitlab.com/hotglue/tap-google-play) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Google Sheets Source: https://docs.hotglue.com/connectors/google-sheets-beta # Connector Details | Name | Value | | :- | :- | | Platform | [Google Sheets](https://sheets.google.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-google-sheets](https://github.com/hotgluexyz/tap-google-sheets) | | Tap Metrics | Usage: (low) | # Google Workspace Source: https://docs.hotglue.com/connectors/google-workspace # Connector Details | Name | Value | | :- | :- | | Platform | [Google Workspace](https://https://workspace.google.com/) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-google-workspace](https://gitlab.com/hotglue/tap-google-workspace) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Google Ads Source: https://docs.hotglue.com/connectors/googleads # Connector Details | Name | Value | | :- | :- | | Platform | [Google Ads](https://ads.google.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-googleads](https://github.com/hotgluexyz/tap-googleads) | | Target Repo | [https://github.com/hotgluexyz/target-googleads](https://github.com/hotgluexyz/target-googleads) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.6 - Add support for campaign\_budget and invoices](https://github.com/hotgluexyz/tap-googleads/releases/tag/v0.0.6) | Add support for campaign\_budget and invoices | # HubSpot Source: https://docs.hotglue.com/connectors/hubspot # Connector Details | Name | Value | | :- | :- | | Platform | [HubSpot](https://hubspot.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-hubspot-beta](https://github.com/hotgluexyz/tap-hubspot-beta) | | Target Repo | [https://gitlab.com/hotglue/target-hubspot-v2](https://gitlab.com/hotglue/target-hubspot-v2) | | Tap Metrics | Usage: (high) | | Target Metrics | Usage: (medium) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| | Target Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Credentials Setup Follow the steps below to get the credentials you need to use the HubSpot connector. Follow the steps below to register the "OAuth App" you need to use the HubSpot connector. This is a one-time process to create your OAuth app. Once you add your app credentials to hotglue, your client will just need to login to their Hubspot account. > 📘 The HubSpot developer account is **different** from a normal HubSpot account. Make sure to register for a Developer Account or you will not see the Manage App options. To start, create a [free HubSpot developer account](https://app.hubspot.com/signup-hubspot/developers). This will give you access to create your app, alongside a Hubspot environment to use in your tests. Once logged into the HubSpot developer portal, your home page should show an **APPS** tab on the top bar. Navigate to the **Apps** tab or click **Manage apps**. ![](https://files.readme.io/aa1a86d-Screen_Shot_2022-05-27_at_2.59.43_PM.png) Once on your Apps page, can click **Create App** to begin setting up your app. Give your app a name, logo, and description. Then, navigate to the Auth tab and add your **Redirect URL**. Unless you've configured a forked redirect URL in hotglue, this needs to be `https://hotglue.xyz/callback`. Click **Create App**. ![](https://files.readme.io/9ab7af0-Screen_Shot_2022-05-27_at_3.14.03_PM.png) The last step is to add your scopes. These are the resources that your users will explicitly authorize you to access. There are two required scope categories: * `oauth` is required for all integrations. * All `crm.schemas` scopes are required for catalog discovery in hotglue. The rest of your scopes will depend on which resources you want to work with in your integration. If you have questions about what your scopes should be, feel free to ask us! ![](https://files.readme.io/86cc9c2-Screen_Shot_2022-05-27_at_3.13.46_PM.png) After you save your updated scopes, you can now copy the three required params to enable your app in hotglue: * Client ID * Client Secret * Install URL You can find all three near the top of the "Auth" section in your Hubspot app. # Features ## Fetch associated records ### Introduction HubSpot supports the concept of [associated records](https://knowledge.hubspot.com/records/associate-records), which enables you to relate a record like a `deal` to another, like a `contact`. In some scenarios, it may be useful to fetch records associated with your selected streams, without fetching the entire associated table. For example, let's say you are running an incremental sync on deals. You may want to fetch the contacts and activities associated with the deals in the each sync. You could do this by selecting `deals`, `contacts`, and `activity`-type streams in your field map. Every job would then fetch all incremental updates for all selected streams, and you could reference related records from within your database. However, if you don't need to replicate each full stream, you can simplify your integration using `fetch_associations`. With `fetch_associations`, the tap only fetches relevant records from related tables that you define. ### The `fetch_associations` object `fetch_associations` is an object set in the connector's config. You can set this via a PATCH to the [linkedSource](https://docs.hotglue.com/api-reference/v1/linked-sources/update-linked-sources) (v1) or [linkedConnector](https://docs.hotglue.com/api-reference/v2/linked-connectors/update) (v2) config. The object contains one or more `` keys (a stream that must already be selected in the field map), each containing a list of one or more `` keys (a stream that may or may not be selected in the field map): ```json theme={null} "fetch_associations":{ :[,] } ``` ### Example usage Below is an example `fetch_associations` entry for deals. In this case, `deals` is the root table selected in our field map, and `contacts` and `tasks` are the related tables to deals that we want to retrieve: ```json theme={null} "fetch_associations":{ "deals":[ "contacts", "tasks" ] } ``` The output from a job using the above will contain 5 tables: * `deals` * `associations_deals_contacts` * `associations_deals_tasks` * `contacts` * `tasks` `deals` contains an incremental sync of deals records. There is no change from normal behavior. The `associations_` tables contain IDs of the `deals` from the stream sync, and the IDs of the related `contacts` and `tasks` records for those deals. `contacts` and `tasks` tables contain the related records which are referenced in `associations_` tables, with an additional `isAssociated` (boolean) column. 💡 In the case where `contacts` is selected separately in the field map, the `contacts` output will contain the normal incremental output, alongside the related deals fetched via association to retrieved `deals`. * You can determine which records were fetched via the incremental sync by filtering `isAssociated==false`. * You can determine which records were fetched via relation by looking to the corresponding `associations_` table. Note that if a contact is both related and part of its own incremental fetch, `isAssociated` will still be `false`. ### Supported tables Supported `` keys are explicitly defined in the HubSpot connector: ```json theme={null} [ "contacts", "meetings", "calls", "communications", "emails", "notes", "postal_mail", "tasks", "companies", "tickets", "products", "quotes", "deals" ] ``` `` keys can be any stream key available in Hubspot's V3 CRM API. This includes custom objects. ### Considerations 1. There may be more than one related record for a given root record. In the above example, your code would need to handle cases where multiple `contacts` and `tasks` are associated with the same root `deal`. 2. If the `` is not selected in the field map, neither that stream nor the related records will sync. This flag is not a replacement for selecting tables in the field map. 3. There are no enforced validations when passing a `fetch_associations` object to a config. You will need to ensure that the `` and `` keys are valid, and that your object is formatted as documented. 4. A PATCH to the connector config cannot be used to add additional keys to an existing `fetch_associations` object. Your PATCH must include the full `fetch_associations` object that you expect to sync. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v2.9.10](https://github.com/hotgluexyz/tap-hubspot/releases/tag/v2.9.10) | | > | [v2.9.9](https://github.com/hotgluexyz/tap-hubspot/releases/tag/v2.9.9) | | > | [v2.9.8](https://github.com/hotgluexyz/tap-hubspot/releases/tag/v2.9.8) | | > | [v2.9.7 - Fix discover for new scopes](https://github.com/hotgluexyz/tap-hubspot/releases/tag/v2.9.7) | - Updated discover to work if users aren't granted full schema access to all streams | > | [v2.9.6 - Add support for companies\_properties](https://github.com/hotgluexyz/tap-hubspot/releases/tag/v2.9.6) | Added support for new stream `companies_properties` based on following HubSpot endpoint: [https://legacydocs.hubspot.com/docs/methods/companies/get\_company\_properties](https://legacydocs.hubspot.com/docs/methods/companies/get_company_properties) | # Imis Source: https://docs.hotglue.com/connectors/imis # Connector Details | Name | Value | | :- | :- | | Tap Repo | [https://github.com/hotgluexyz/tap-imis](https://github.com/hotgluexyz/tap-imis) | | Tap Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| # Sage Intacct Source: https://docs.hotglue.com/connectors/intacct # Connector Details | Name | Value | | :- | :- | | Platform | [Sage Intacct](https://sageintacct.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-intacct](https://github.com/hotgluexyz/tap-intacct) | | Target Repo | [https://github.com/hotgluexyz/target-intacct-v2](https://github.com/hotgluexyz/target-intacct-v2) | | Tap Metrics | Usage: (high) Success Rate: (high) | | Target Metrics | Usage: (medium) Success Rate: (high) | | Unified Schema | Supported in [Accounting Unified Schema](https://hotglue.com/docs/unified). (Supported tables: Accounts, Classes, BankAccounts, Vendors, Projects, Departments, Locations) | # Credentials Setup Follow the steps below to get the credentials you need to use the Sage Intacct connector. The Sage Intacct tap requires the following fields: | Field Name | Description | | :- | :- | | Company Id | Your Sage Intacct Company Id | | Sender Id | Your Sage Intacct Sender Id | | Sender Password | Your Sage Intacct Sender Password | | User Id | Your Sage Intacct User Id | | User Password | Your Sage Intacct User Password | ### 1. Enable Web Services To enable Web Services, go to Company > Admin > Subscriptions ![Navigate to Subscription](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Navigate%20to%20Subscription.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=74877d92b8b4a8fcae6639adede34946) Ensure “Web Services” is enabled ![Web Services Toggle](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Web%20Services%20Toggle.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=f97ddbd26765a85ca6cb6891cd43328e) ### 2. Generate a Sender ID and password The Intacct Sender credentials are used to validate your API access. Unfortunately, Intacct does not provide API access to all users by default. You have two options for obtaining developer credentials. 1. You (the hotglue customer) can register as an Intacct Marketplace partner (link to Intacct page of applying to be a marketplace partner). This involves an approval process that typically takes a couple of months. hotglue can then use your Sender credentials to interact with your tenants' Intacct instances. ([More Information](https://www.sage.com/en-us/sage-business-cloud/intacct/partners/)) 2. Your tenant can obtain a developer license, which includes sender credentials. This is paid, however does not involve a lengthy approval process. ([More information](https://developer.sage.com/)) ### 3. Authorize the Sender ID Go to Company > Setup > Company > Security, and select Edit ![Navigate to Security](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Navigate%20to%20Security.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=925b61e4e65b100ffbdde98d0f2b1871) In the Web Services authorizations section, select Add ![Add Web Service Profile](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Add%20Web%20Service%20Profile.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=9cbcf6ddf803bda8330081cda7c33f94) Enter the Sender ID (provided externally), set as Active, select Save ![Web Services Sender info](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Web%20Services%20Sender%20info.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=7609a08e1f63d6b47aa4d503816efb44) ### 4. Create a role to be used by the hotglue integration Navigate to Company > Admin > Roles ![Navigate to Roles](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Navigate%20to%20Roles.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=a1a8d861c2239f6d0653285cad911e4e) Select Add ![Adding a new Role](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Adding%20a%20new%20Role.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=2fee30a40a9732abecb29c4b3740af9b) Name the role and select Save ![Naming and Saving Role](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Naming%20and%20Saving%20Role.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=aacd1a477ab2896322f9a305df2965ae) You should configure this role's permissions based on your hotglue integration. For example, if are you looking to both read and write journal entries, you should make sure to give full permissions for the General Ledger. If you are only reading from Intacct, you can select omnit write access. ![Permissions Setup](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Permissions%20Setup.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=7e6ca6e6837040d1d601e8b7a004adee) ### 4. Create the Intacct user to be used by the hotglue integration Go to Company > Admin > Users ![Navigate to Users](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Navigate%20to%20Users.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=72a410e5021442c2da02bceb18423863) Select Add ![Add a new User](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Add%20a%20new%20User.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=647ad8654fbd7135ef00ae4cc60488b4) Create a login-enabled user for the integration: 1. User ID: (this becomes the `user_id` field) 2. Username/email 3. Set password (this becomes the `user_password`) ![Add User info](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Add%20User%20info.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=9be6745374f2695fddba29175d6138a5) ### 5. Assign the role to the user Go to Company → Admin → Users. Open the integration user you created and select Edit. Scroll down to the Roles section on the user record. Select Add. Choose the integration role you created earlier. Select Save on the user record. Note: The Company > Admin > Roles > Role assignment screen only shows assignments; you cannot add users there. ### 6. Find the Company ID Finally, open Company > Setup > Company ![Navigate to Company](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Navigate%20to%20Company.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=ff0b1a2c09e92aac8f4ce2b15f24ba14) Copy the Company ID shown (this becomes `company_id`) ![Get Company ID](https://mintcdn.com/hotglue/-53LQeOTMO8Kp5it/connectors/images/Get%20Company%20ID.png?fit=max\&auto=format\&n=-53LQeOTMO8Kp5it\&q=85\&s=c87f87026538041eaf6151d4e4f8a72a) All done! You’re ready to use Sage Intacct integration via hotglue. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.1.7](https://github.com/hotgluexyz/tap-intacct/releases/tag/v0.1.7) | | > | [v0.1.6](https://github.com/hotgluexyz/tap-intacct/releases/tag/v0.1.6) | | > | [v0.1.5](https://github.com/hotgluexyz/tap-intacct/releases/tag/v0.1.5) | | > | [v0.1.4](https://github.com/hotgluexyz/tap-intacct/releases/tag/v0.1.4) | | > | [v0.1.3 - Dynamic catalog generation](https://github.com/hotgluexyz/tap-intacct/releases/tag/v0.1.3) | - Handle generating catalog dynamically | > | [v0.1.2 - Add support for support ARINVOICE, ARADJUSTMENT, CUSTOMER & ITEM](https://github.com/hotgluexyz/tap-intacct/releases/tag/v0.1.2) | Added support for ARINVOICE, ARADJUSTMENT, CUSTOMER & ITEM objects | > | [Change name to tap-intacct](https://github.com/hotgluexyz/tap-intacct/releases/tag/v0.1.1) | This is a fork of original `tap-intacct-api` - hotglue is maintaining this fork. | # Intercom Source: https://docs.hotglue.com/connectors/intercom # Connector Details | Name | Value | | :- | :- | | Platform | [Intercom](https://intercom.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-intercom](https://github.com/hotgluexyz/tap-intercom) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Intercom connector. To get your OAuth credentials for Intercom, you are first going to need to log in to [Intercom](https://app.intercom.com/admins/sign_in?on_pageview_event=sign_in_nav). ![](https://files.readme.io/2bcc774-login_Intercom.PNG.png "login_Intercom.PNG.png") Now that you are on the Intercom home page, go to the bottom left of the page and click on your account icon. ![](https://files.readme.io/0a7ef07-Login_settings.png "Login_settings.png") Select the Settings tab. ![](https://files.readme.io/9fc8412-APP_and_Integration-Click.png "APP and Integration-Click.png") Select the Apps & Integrations option in the left-sided nav bar. ![](https://files.readme.io/2ff59aa-DevelopersHub.png "DevelopersHub.png") Under Apps & Intergations, click on Developer Hub. ![](https://files.readme.io/d78e4f5-New_APP_Click.png "New_APP_Click.png") Click on **New app**. ![](https://files.readme.io/672df5c-New_APP_Form_Fill.png "New_APP_Form_Fill.png") Input App name and other fields and Click **Create app** button. Remember, this should be the name of your app, not hotglue. ![](https://files.readme.io/f6b61a5-Authentication_Add_url.png "Authentication_Add_url.png") Navigate to “Authentication” Menu. Click on “Edit” button. ![](https://files.readme.io/877c619-Save_button_add_auth.png "Save_button_add_auth.png") Check off “Use OAuth” under the OAuth tab, and then add `https://hotglue.xyz/callback` as the Redirect URL. Save the changes by clicking the Save button in the top right hand corner. ![](https://files.readme.io/64b8142-TEFDFDFDFD.png "TEFDFDFDFD.png") Then head to the Basic Information option via the left-sided nav bar. You should now be able to copy the Intercom OAuth Client ID and Client Secret into hotglue. You have now gotten your credentials for Intercom! # Invoiced Source: https://docs.hotglue.com/connectors/invoiced # Connector Details | Name | Value | | :- | :- | | Platform | [Invoiced](https://invoiced.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-invoiced](https://github.com/hotgluexyz/tap-invoiced) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Iterable Source: https://docs.hotglue.com/connectors/iterable # Connector Details | Name | Value | | :- | :- | | Platform | [Iterable](https://iterable.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-iterable](https://gitlab.com/hotglue/tap-iterable) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Iterable connector. The first thing you will need to do get your Iterable credentials is have an Iterable account. There is no easy way to get access to a free account, so let us know if you don't have an account. If you do already have an account, you can [log in at this link](https://app.iterable.com/login). ## API Key We are going to go through how to find your API key. ![](https://files.readme.io/1db957b-Screen_Shot_2022-01-18_at_12.23.46_PM.png "Screen Shot 2022-01-18 at 12.23.46 PM.png") Once you have logged in to Iterable, you will be shown the home page of the Iterable platform. On the menu bar on the top of the page, hover over the tab that is called **Integrations**. ![](https://files.readme.io/bf30dea-Screen_Shot_2022-01-18_at_12.25.26_PM.png "Screen Shot 2022-01-18 at 12.25.26 PM.png") From the prompted drop down, select the **API keys** option. ![](https://files.readme.io/f12a5f5-Screen_Shot_2022-01-18_at_12.28.51_PM.png "Screen Shot 2022-01-18 at 12.28.51 PM.png") You will now be on your API keys page. Go ahead and click on the **New API Key** button in the upper right hand side of your screen. ![](https://files.readme.io/f94d0d2-Screen_Shot_2022-01-18_at_12.33.36_PM.png "Screen Shot 2022-01-18 at 12.33.36 PM.png") You most likely want to call your API key "hotglue" or something similar. You also want to make your API key a **Server-side** key. Once you are done with that, click the Create button. ![](https://files.readme.io/a2d7bc9-Screen_Shot_2022-01-18_at_12.36.42_PM.png "Screen Shot 2022-01-18 at 12.36.42 PM.png") You will now be shown your API key. Make sure to note this down somewhere safe! As Iterable says, they will only show you this key once. You should now copy it into hotglue and you are all done getting your credentials! # iTunes Source: https://docs.hotglue.com/connectors/itunes # Connector Details | Name | Value | | :- | :- | | Platform | [iTunes](https://itunes.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-itunes](https://gitlab.com/hotglue/tap-itunes) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Jira Source: https://docs.hotglue.com/connectors/jira # Connector Details | Name | Value | | :- | :- | | Platform | [Jira](https://atlassian.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-jira](https://github.com/hotgluexyz/tap-jira) | | Target Repo | [https://gitlab.com/hotglue/target-jira](https://gitlab.com/hotglue/target-jira) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Jira connector. The first thing that you need to do to get your Jira OAuth credentials is to [login](https://id.atlassian.com/login?continue=https%3A%2F%2Fdeveloper.atlassian.com%2F%2F) in to Jira's Developer console. If you do not have a Jira account, you can create a free one [here](https://www.atlassian.com/try/cloud/signup?bundle=jira-software\&edition=free). ![](https://files.readme.io/4665011-Screen_Shot_2021-12-24_at_11.28.04_AM.png "Screen Shot 2021-12-24 at 11.28.04 AM.png") Now that you have logged into Jira, you need to actually head the developer console. Your home page should look similar to this. Head to top right hand corner of the page and click on the icon with your initial in it. ![](https://files.readme.io/d1644d5-Screen_Shot_2021-12-24_at_11.28.41_AM.png "Screen Shot 2021-12-24 at 11.28.41 AM.png") ## Creating the app Now from the resulting drop down, you should click the **Developer console** tab. ![](https://files.readme.io/b250100-Screen_Shot_2021-12-24_at_11.31.13_AM.png "Screen Shot 2021-12-24 at 11.31.13 AM.png") You should now be on this page. To create an OAuth app, click on the **Create** button on the right side of the screen. ![](https://files.readme.io/c6655bc-Screen_Shot_2021-12-24_at_11.32.05_AM.png "Screen Shot 2021-12-24 at 11.32.05 AM.png") When it asks you what kind of app you would like to create, make sure to select the **OAuth 2.0 integration** option. ![](https://files.readme.io/9cfe511-Screen_Shot_2021-12-24_at_11.33.07_AM.png "Screen Shot 2021-12-24 at 11.33.07 AM.png") On this page, you should go ahead and name your private app as **your** company name, not hotglue. Remember, this is the app your customers will be seeing when they are connecting their Jira account to your platform. Once you are done inputting your app name (and agreeing to the Atlassian developer terms), click create. ## Configuring Permissions ![](https://files.readme.io/9ade411-Screen_Shot_2021-12-24_at_11.34.53_AM.png "Screen Shot 2021-12-24 at 11.34.53 AM.png") On this page, you have the ability to edit the details of your application. The first thing you should do is head to the **Permissions** section of your app. ![](https://files.readme.io/7f57042-Screen_Shot_2021-12-24_at_11.37.12_AM.png "Screen Shot 2021-12-24 at 11.37.12 AM.png") On this page, you can configure the scopes of your OAuth app. Go ahead and click **Add** on any of the scopes you would like to enable. ![](https://files.readme.io/f6e1ebf-Screen_Shot_2021-12-24_at_11.39.16_AM.png "Screen Shot 2021-12-24 at 11.39.16 AM.png") As you can see here, I have added some scopes to my app. It is important that you go in and configure each API in order to make sure the permissions you want are set. For this example, let's do this with the Jira platform REST API. ![](https://files.readme.io/b170306-Screen_Shot_2021-12-24_at_11.40.25_AM.png "Screen Shot 2021-12-24 at 11.40.25 AM.png") When you add the scopes for the Jira platform REST API, it defaults to just enabling the View user profiles permission. Since I want to be able to read into issue data, I am also going to add the View Jira issue data scope. **Note: If you are only going to use this app to read data from Jira, you will only need to check scopes that can View objects in Jira. If you are also planning on writing data to Jira, you should add the Create/Manage scopes as well as the View scopes.** ![](https://files.readme.io/3104f30-Screen_Shot_2021-12-24_at_11.45.39_AM.png "Screen Shot 2021-12-24 at 11.45.39 AM.png") Once you are done configuring the scopes, you can go ahead and head back to your app. ## Getting the credentials Now it is finally time to grab your credentials. ![](https://files.readme.io/acaee86-Screen_Shot_2021-12-24_at_11.46.33_AM.png "Screen Shot 2021-12-24 at 11.46.33 AM.png") Head into the **App details** section of your app. ![](https://files.readme.io/94f617e-Screen_Shot_2021-12-24_at_11.47.16_AM.png "Screen Shot 2021-12-24 at 11.47.16 AM.png") At the bottom of this page, you can access your credentials! Take these and put them in hotglue. # Jotform Source: https://docs.hotglue.com/connectors/jotform # Connector Details | Name | Value | | :- | :- | | Platform | [Jotform](https://jotform.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-jotform](https://gitlab.com/hotglue/tap-jotform) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Jotform connector. Login [here](https://www.jotform.com/myforms/). You will land on the All Forms page. ![](https://files.readme.io/660a5a4-image.png) Click on your account name at the top right. A new form will open. Scroll down and click on **Settings**. ![](https://files.readme.io/7f00f19-image.png) A new tab will open. Select the API option from right navigation pane. ### Create a new REST API key Create your new consumer key pair. You can set the Permission levels. For the Jotform source, you only need to provide Read level permissions. ![](https://files.readme.io/5e608a3-image.png) That's it! Insert API Secret into your hotglue Jotform source settings. # Judge.me Source: https://docs.hotglue.com/connectors/judgeme # Connector Details | Name | Value | | :- | :- | | Platform | [Judge.me](https://judge.me) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-judgeme](https://gitlab.com/hotglue/tap-judgeme) | | Tap Metrics | Usage: (high) Success Rate: (high) | # Kafka Source: https://docs.hotglue.com/connectors/kafka # Connector Details | Name | Value | | :- | :- | | Platform | [Apache Kafka](https://kafka.apache.org/) | | Auth Type | Broker-dependent (e.g. SASL, TLS) | | Direction | Write | | Target Repo | [https://github.com/hotgluexyz/target-kafka](https://github.com/hotgluexyz/target-kafka) | # Target Kafka `target-kafka` writes Singer streams to Kafka topics using a producer. Each stream name maps to a topic name unless you override it (see `stream_topic_map`). Records are sent as message payloads for that topic. ## Config Set at least **bootstrap\_servers**. If your brokers require SASL, set **sasl\_username** and **sasl\_password**; the target picks sensible defaults for `security_protocol` and `sasl_mechanism` when those are present. Expand the table below for every option. ```json theme={null} { "bootstrap_servers": "broker1.example.com:9092,broker2.example.com:9092", "sasl_username": "...", "sasl_password": "...", "topic_prefix": "", "client_id": "target-kafka" } ``` ## Configuration reference | Property | Description | Default | | - | - | - | | `bootstrap_servers` | Comma-separated `host:port` list for Kafka bootstrap brokers. | (required) | | `sasl_username` | SASL username when using SASL (for example PLAIN). | — | | `sasl_password` | SASL password paired with `sasl_username`. Treat as a secret. | — | | `security_protocol` | `PLAINTEXT`, `SSL`, `SASL_PLAINTEXT`, or `SASL_SSL`. If omitted, the target uses `SASL_SSL` when `sasl_username` and `sasl_password` are set, otherwise `PLAINTEXT`. | inferred | | `sasl_mechanism` | SASL mechanism when the protocol is SASL-based (e.g. `PLAIN`, `SCRAM-SHA-256`). | `PLAIN` | | `topic_prefix` | String prepended to each stream name when resolving the Kafka topic. | `""` | | `stream_topic_map` | Object mapping stream names to topic names; entries override `topic_prefix` + stream name. | — | | `client_id` | Client id the producer reports to the cluster. | `target-kafka` | | `flush_timeout` | Seconds to wait for in-flight messages when flushing on state drain or shutdown. | `30` | | `extra_producer_config` | Extra producer settings merged into the client (librdkafka-style keys, e.g. `compression.type`, `linger.ms`). | — | # Katana MRP Source: https://docs.hotglue.com/connectors/katana # Connector Details | Name | Value | | :- | :- | | Platform | [Katana MRP](https://katanamrp.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-katana](https://gitlab.com/hotglue/tap-katana) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Keap Source: https://docs.hotglue.com/connectors/keap # Connector Details | Name | Value | | :- | :- | | Platform | [Keap](https://keap.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Triggers | Supported (1 triggers available by default) | | Tap Repo | [https://gitlab.com/hotglue/tap-keap](https://gitlab.com/hotglue/tap-keap) | | Target Repo | [https://gitlab.com/hotglue/target-keap](https://gitlab.com/hotglue/target-keap) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Klaviyo Source: https://docs.hotglue.com/connectors/klaviyo # Connector Details | Name | Value | | :- | :- | | Platform | [Klaviyo](https://klaviyo.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-klaviyo-v2](https://github.com/hotgluexyz/tap-klaviyo-v2) | | Target Repo | [https://github.com/hotgluexyz/target-klaviyo](https://github.com/hotgluexyz/target-klaviyo) | | Tap Metrics | Usage: (high) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (medium) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| # Credentials Setup Follow the steps below to get the credentials you need to use the Klaviyo connector. The first thing you will need to do get your Klaviyo credentials is make an Klaviyo account. You can [make a free account (or sign up for a paid account) at this link](https://www.klaviyo.com/pricing?emailListSize=0\&smsContacts=0). If you already have an account, you can [log in at this link](https://www.klaviyo.com/login). ## API Key First, we are going to go through how to find your personal API key. ![](https://files.readme.io/d61b062-Screen_Shot_2021-11-23_at_3.56.15_PM.png "Screen Shot 2021-11-23 at 3.56.15 PM.png") Once you have logged in to Klaviyo, you will be shown the home page of the Klaviyo platform. In the top right corner, there is an icon with your initial and company name. Go ahead and click that icon. ![](https://files.readme.io/c66bca3-Screen_Shot_2021-11-23_at_4.00.17_PM.png "Screen Shot 2021-11-23 at 4.00.17 PM.png") Now go ahead and click on the Account tab from the drop down. ![](https://files.readme.io/afcc4c4-Screen_Shot_2021-11-23_at_4.02.11_PM.png "Screen Shot 2021-11-23 at 4.02.11 PM.png") You will now be on your account page. Go ahead and click on the **Settings** tab in the upper right hand side of your screen. ![](https://files.readme.io/1df8edf-Screen_Shot_2021-11-23_at_4.03.07_PM.png "Screen Shot 2021-11-23 at 4.03.07 PM.png") Go ahead and select **API Keys** from the resulting dropdown. ![](https://files.readme.io/584eb9b-Screen_Shot_2021-11-23_at_4.04.35_PM.png "Screen Shot 2021-11-23 at 4.04.35 PM.png") Now you will be on a page where you can generate the API Key for hotglue. ![](https://files.readme.io/0f01314-Screen_Shot_2021-11-23_at_4.23.05_PM.png "Screen Shot 2021-11-23 at 4.23.05 PM.png") You should go ahead and click the **Create Private API Key** button. ![](https://files.readme.io/b6932ba-Screen_Shot_2021-11-23_at_4.23.05_PM.png "Screen Shot 2021-11-23 at 4.23.05 PM.png") You should go ahead and name the API Key **hotglue**. Start this process by clicking the pencil icon under the label section. ![](https://files.readme.io/9fdbe0f-Screen_Shot_2021-11-23_at_4.26.47_PM.png "Screen Shot 2021-11-23 at 4.26.47 PM.png") Once you've typed in hotglue, click **Save Label**. ![](https://files.readme.io/50af10b-Screen_Shot_2021-11-23_at_4.28.44_PM.png "Screen Shot 2021-11-23 at 4.28.44 PM.png") Now you should go ahead and copy your API Key. Do this by clicking the reveal button next to the API Key. ![](https://files.readme.io/ec2b645-Screen_Shot_2021-11-23_at_4.30.31_PM.png "Screen Shot 2021-11-23 at 4.30.31 PM.png") Now go ahead and copy that API key and paste it into hotglue! # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.2 – Updated catalog to match Singer spec](https://github.com/hotgluexyz/tap-klaviyo/releases/tag/v0.0.2) | - Updated discover output to generate `metadata` according to Singer spec - Updated sync logic to use `selected` value from `metadata` in `catalog` rather than from `schema` entry | # KPA Source: https://docs.hotglue.com/connectors/kpa # Connector Details | Name | Value | | :- | :- | | Platform | [KPA](https://kpa.io) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-kpa](https://github.com/hotgluexyz/tap-kpa) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Kustomer Source: https://docs.hotglue.com/connectors/kustomer # Connector Details | Name | Value | | :- | :- | | Platform | [Kustomer](https://kustomer.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-kustomer](https://gitlab.com/hotglue/tap-kustomer) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Lightspeed (C-Series) Source: https://docs.hotglue.com/connectors/lightspeed # Connector Details | Name | Value | | :- | :- | | Platform | [Lightspeed (C-Series)](https://lightspeedhq.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-lightspeed](https://github.com/hotgluexyz/tap-lightspeed) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Unified Schema | Supported in [Ecommerce Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders, Products) | # Linear Source: https://docs.hotglue.com/connectors/linear # Connector Details | Name | Value | | :- | :- | | Platform | [Linear](https://linear.app) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-linear](https://github.com/hotgluexyz/tap-linear) | | Tap Metrics | Usage: (low) Success Rate: (high) | # LinkedIn Ads Source: https://docs.hotglue.com/connectors/linkedin-ads # Connector Details | Name | Value | | :- | :- | | Platform | [LinkedIn Ads](https://linkedin.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/singer-io/tap-linkedin-ads](https://github.com/singer-io/tap-linkedin-ads) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Linnworks Source: https://docs.hotglue.com/connectors/linnworks # Connector Details | Name | Value | | :- | :- | | Platform | [Linnworks](https://linnworks.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-linnworks](https://github.com/hotgluexyz/tap-linnworks) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # LiveChat Source: https://docs.hotglue.com/connectors/livechat # Connector Details | Name | Value | | :- | :- | | Platform | [LiveChat](https://livechat.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-livechat](https://gitlab.com/hotglue/tap-livechat) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Logic4 Source: https://docs.hotglue.com/connectors/logic4 # Connector Details | Name | Value | | :- | :- | | Platform | [Logic4](https://logic4.nl) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-logic4](https://github.com/hotgluexyz/tap-logic4) | | Target Repo | [https://github.com/hotgluexyz/target-logic4](https://github.com/hotgluexyz/target-logic4) | | Tap Metrics | Usage: (low) Success Rate: (high) | | Target Metrics | Usage: (medium) Success Rate: (high) | # Looker Source: https://docs.hotglue.com/connectors/looker # Connector Details | Name | Value | | :- | :- | | Platform | [Looker](https://looker.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-looker](https://gitlab.com/hotglue/tap-looker) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Magento 2 Source: https://docs.hotglue.com/connectors/magento # Connector Details | Name | Value | | :- | :- | | Platform | [Magento 2](https://magento.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-magento](https://github.com/hotgluexyz/tap-magento) | | Target Repo | [https://gitlab.com/hotglue/target-magento](https://gitlab.com/hotglue/target-magento) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (low) | | Unified Schema | Supported in [Ecommerce Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders, Products, Customers, Carts, Refunds) | # Credentials Setup Follow the steps below to get the credentials you need to use the Magento 2 connector. The Magento connector requires three fields. If you do not have Magento credentials, contact us about using the hotglue testing account. 1. **Store URL** - The Store URL is usually the domain that is assigned to your IP address. This is usually the root. If you do not yet have a domain, your store URL will include a series of four numbers, each separated by a period in dotted quad notation. 2. **Username** - This is the username you use to log into your Magento account 3. **Password** - This is the password you use to log into your Magento account # Magento 1 Source: https://docs.hotglue.com/connectors/magento-v1 # Connector Details | Name | Value | | :- | :- | | Platform | [Magento 1](https://magento.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-magento-v1](https://gitlab.com/hotglue/tap-magento-v1) | | Tap Metrics | Usage: (low) | # Mailchimp Source: https://docs.hotglue.com/connectors/mailchimp # Connector Details | Name | Value | | :- | :- | | Platform | [Mailchimp](https://mailchimp.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Triggers | Supported (6 triggers available by default) | | Tap Repo | [https://github.com/hotgluexyz/tap-mailchimp](https://github.com/hotgluexyz/tap-mailchimp) | | Target Repo | [https://github.com/hotgluexyz/target-mailchimp-v2](https://github.com/hotgluexyz/target-mailchimp-v2) | | Tap Metrics | Usage: (medium) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Mailchimp connector. To get your Mailchimp OAuth Client ID and OAuth Client Secret, go ahead and [log in to Mailchimp](https://mailchimp.com/login). ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRrHhfXAeYBhvMZZLS%2F-MgRuG3lbYLR-ml2V4xT%2FScreen%20Shot%202021-08-06%20at%203.19.51%20PM.png?alt=media\&token=2eb55371-52e6-43ab-a959-4ef0ca5fe020) Once you are logged in, click your account picture in the bottom left hand corner of the page. This will trigger a menu to pop-up. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRrHhfXAeYBhvMZZLS%2F-MgRu_-Od5w70Oa8Nrl0%2FScreen%20Shot%202021-08-06%20at%203.21.23%20PM.png?alt=media\&token=aeae4a4b-fc54-432b-9189-66a4e3ec2591) In this menu, go ahead and select the Account tab. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRrHhfXAeYBhvMZZLS%2F-MgRvHrWkxepR1K5hevr%2FScreen%20Shot%202021-08-06%20at%203.24.53%20PM.png?alt=media\&token=bcadcc35-5d8c-49a2-955c-0a60707d58ae) On the Account page, go ahead and click the Extras to prompt the drop down. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRrHhfXAeYBhvMZZLS%2F-MgRw8TeO1QX3aG6IoGu%2FScreen%20Shot%202021-08-06%20at%203.28.38%20PM.png?alt=media\&token=8ddfce75-9506-4ebf-9359-c7cddb90adad) From the resulting drop down, select the Registered apps tab. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgRy2jhnCnpxpqHlDJ3%2F-MgRyyz7f6eJ7N8Z-1rT%2FScreen%20Shot%202021-08-06%20at%203.37.35%20PM.png?alt=media\&token=57e1f39a-4998-4c8f-b045-ed65571a69a2) Now you should go ahead and begin registering your app. To do that, click the Register An App button. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgS0yLiFpGLiVrw_J-o%2F-MgS3YTNh54QtbpzI7-9%2FScreen%20Shot%202021-08-06%20at%204.05.30%20PM.png?alt=media\&token=f5f7129e-f8bc-4869-a92c-535deeff8523) You will now be on this page where you should fill in your information. Make sure that you set the Redirect URL to: ```text theme={null} https://hotglue.xyz/callback ``` Once you have filled everything in, click the Create button. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgS4_sscubIu2ftTSeW%2F-MgS5YQ7jsbehUy89Hgj%2FScreen%20Shot%202021-08-06%20at%204.12.41%20PM.png?alt=media\&token=13fbfcba-ac57-425a-b3c1-813f96d6c8da) You will now have your credentials! Take these credentials and copy them into hotglue. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.1.4](https://github.com/hotgluexyz/tap-mailchimp/releases/tag/v1.1.4) | | > | [v1.1.3](https://github.com/hotgluexyz/tap-mailchimp/releases/tag/v1.1.3) | Minor change to the way catalog is generated to play nicely with other tools. Needed to include a `metadata` entry with a `breadcrumb: []` | # MailerLite Source: https://docs.hotglue.com/connectors/mailerlite # Connector Details | Name | Value | | :- | :- | | Platform | [MailerLite](https://mailerlite.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-mailerlite](https://gitlab.com/hotglue/tap-mailerlite) | | Target Repo | [https://gitlab.com/hotglue/target-mailerlite](https://gitlab.com/hotglue/target-mailerlite) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the MailerLite connector. The first thing you need to do is log in to [Mailerlite](https://accounts.mailerlite.com/). ![](https://files.readme.io/4aba621-mailerlite-01.png "mailerlite-01.png") Login page will shown-up. ![](https://files.readme.io/dd6dbd8-mailerlite-02.png "mailerlite-02.png") Enter the credentials and click on **Log in** button. ![](https://files.readme.io/bb3643d-mailerlite-03.png "mailerlite-03.png") You will land on Dashboard page. ![](https://files.readme.io/2a2a41e-mailerlite-04.png "mailerlite-04.png") Click on **Account settings** from left nav pane. Enter company name and website and other information. ![](https://files.readme.io/f46991f-mailerlite-05.png "mailerlite-05.png") Navigate back to Dashboard from highlighted button. ![](https://files.readme.io/ac23884-mailerlite-06.png "mailerlite-06.png") Select **Integrations** from left nav-pane. ![](https://files.readme.io/d13ab53-mailerlite-07.png "mailerlite-07.png") Click on Use button. ![](https://files.readme.io/5946859-mailerlite-08.png "mailerlite-08.png") Click on **Generate new token** button to get the token. ![](https://files.readme.io/c6934de-mailerlite-09.png "mailerlite-09.png") Enter the name of token and click on Create token button. ![](https://files.readme.io/b12ea9d-mailerlite-10.png "mailerlite-10.png") Now you can go ahead and copy API token into hotglue. # Mailgun Source: https://docs.hotglue.com/connectors/mailgun # Connector Details | Name | Value | | :- | :- | | Platform | [Mailgun](https://mailgun.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-mailgun](https://github.com/hotgluexyz/tap-mailgun) | | Target Repo | [https://github.com/hotgluexyz/target-mailgun](https://github.com/hotgluexyz/target-mailgun) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Mailgun connector. ## Private Key The first thing you need to do is log in to [Mailgun](https://mailgun.com). They have a free tier, so if you don't have an account, you can make one. ![](https://files.readme.io/9dd7671-Screen_Shot_2022-01-03_at_7.13.03_PM.png "Screen Shot 2022-01-03 at 7.13.03 PM.png") Your home page should look something like this. On the bottom left side of the screen, you should click on the **Settings** option. ![](https://files.readme.io/debc589-Screen_Shot_2022-01-03_at_6.50.20_PM.png "Screen Shot 2022-01-03 at 6.50.20 PM.png") You should now see a menu of items. You should go ahead and select the **API Keys** option. ![](https://files.readme.io/3c88481-Screen_Shot_2022-01-03_at_6.51.50_PM.png "Screen Shot 2022-01-03 at 6.51.50 PM.png") Now you should see your keys. Go ahead an unveil the **Private API Key** by clicking the eye icon. Once you do that, you should copy this key into hotglue! # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.1.1 - Add support for members, mailing\_lists](https://github.com/hotgluexyz/tap-mailgun/releases/tag/v0.1.1) | Add support for `members` and `mailing_lists` | # Target Changelog > [accordion] Target Changelog > > | Version | Notes | > | :- | :- | > | [v1.0.0 - Mailgun target](https://github.com/hotgluexyz/target-mailgun/releases/tag/v1.0.0) | Allows you to send any files as attachments in an email using Mailgun | # Mailjet Source: https://docs.hotglue.com/connectors/mailjet # Connector Details | Name | Value | | :- | :- | | Platform | [Mailjet](https://mailjet.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-mailjet](https://gitlab.com/hotglue/tap-mailjet) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Mailshake Source: https://docs.hotglue.com/connectors/mailshake # Connector Details | Name | Value | | :- | :- | | Platform | [Mailshake](https://mailshake.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-mailshake](https://github.com/hotgluexyz/tap-mailshake) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Mailstep Source: https://docs.hotglue.com/connectors/mailship # Connector Details | Name | Value | | :- | :- | | Platform | [Mailstep](https://mailstep.cz) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-mailship](https://gitlab.com/hotglue/tap-mailship) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Marketplacer Source: https://docs.hotglue.com/connectors/marketplacer # Connector Details | Name | Value | | :- | :- | | Platform | [Marketplacer](https://marketplacer.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Triggers | Supported (6 triggers available by default) | | Tap Repo | [https://gitlab.com/hotglue/tap-marketplacer](https://gitlab.com/hotglue/tap-marketplacer) | | Target Repo | [https://gitlab.com/hotglue/target-marketplacer](https://gitlab.com/hotglue/target-marketplacer) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | | Unified Schema | Supported in [Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders, Products) | # Medusa Source: https://docs.hotglue.com/connectors/medusa # Connector Details | Name | Value | | :- | :- | | Platform | [Medusa](https://medusajs.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-medusa](https://github.com/hotgluexyz/tap-medusa) | | Tap Metrics | Usage: (low) Success Rate: (high) | | Unified Schema | Supported in [Ecommerce Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders, Products, Refunds) | # Meta Ads Source: https://docs.hotglue.com/connectors/meta-ads # Connector Details | Name | Value | | :- | :- | | Target Repo | [https://github.com/hotgluexyz/target-meta-ads](https://github.com/hotgluexyz/target-meta-ads) | | Target Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| # Metronome Source: https://docs.hotglue.com/connectors/metronome # Connector Details | Name | Value | | :- | :- | | Platform | [Metronome](https://metronome.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-metronome](https://gitlab.com/hotglue/tap-metronome) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Mixpanel Source: https://docs.hotglue.com/connectors/mixpanel # Connector Details | Name | Value | | :- | :- | | Platform | [Mixpanel](https://mixpanel.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-mixpanel](https://github.com/hotgluexyz/tap-mixpanel) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Mixpanel connector. The first thing you need to do is log in to Mixpanel and open the **project** you want to connect. ![](https://files.readme.io/4485024-create-acc-03.png) Click on the Settings button and select **Project Settings**. ![](https://files.readme.io/b467af1-create-acc-04.png) Scroll down to the page and you will find API Secret. Now you can insert API Secret into your hotglue Mixpanel source settings. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.2.16](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.16) | | > | [v1.2.15](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.15) | | > | [v1.2.14](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.14) | - Added logic to ignore malformed records | > | [v1.2.13 - Disable date-time validation](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.13) | - Disable date-time validation as it is not enforced by Mixpanel | > | [v1.2.12 - Update 500 response handler](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.12) | Treat all 500 errors the same, and skip the record | > | [v1.2.11 - Change error handling](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.11) | Instead of retrying requests when getting json parse errors, just print a warning and skip the payload | > | [v1.2.10 - Add retry logic](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.10) | - Add retry logic to handle malformed responses from API | > | [v1.2.9 – Bump page\_limit param](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.9) | - Bumped `page_limit` from 200 to 1,000 to increase sync speed | > | [v1.2.8 - Fix bug with pulling unsubscribed](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.8) | - Handle pulling `mp_reserved_unsubscribed` property (with the malformed entries as `'false'`) | > | [v1.2.7 – Handle malformed cohorts](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.7) | - Handle malformed cohort error from Mixpanel (skipping that cohort) | > | [v1.2.6 - Fix incorrect cohort\_members output](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.6) | - Updated logic to use a unique session id when requesting `cohort_members` to avoid pulling incorrect cached results from a past query | > | [v1.2.5 - Pagination fixes](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.5) | Fixed bug which caused pagination to stop working when querying `cohort_members` | > | [v1.2.2 - Bug fixes](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.2) | - Fixed bug which caused execution of tap to fail when "unexpected error" from MIxpanel API was hit | > | [v1.2.1 - Handle group with cohorts of different groups](https://github.com/hotgluexyz/tap-mixpanel/releases/tag/v1.2.1) | - Fixed bug which caused execution of tap to fail with error `Cannot query one group with cohorts of different groups` when syncing `cohort_members` | # Monday.com Source: https://docs.hotglue.com/connectors/monday # Connector Details | Name | Value | | :- | :- | | Platform | [Monday.com](https://monday.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-monday](https://gitlab.com/hotglue/tap-monday) | | Tap Metrics | Usage: (low) Success Rate: (high) | # MongoDB Source: https://docs.hotglue.com/connectors/mongodb # Connector Details | Name | Value | | :- | :- | | Platform | [MongoDB](https://mongodb.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-mongodb](https://github.com/hotgluexyz/tap-mongodb) | | Target Repo | [https://github.com/hotgluexyz/target-mongodb](https://github.com/hotgluexyz/target-mongodb) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (low) | # Credentials Setup Follow the steps below to get the credentials you need to use the MongoDB connector. First, we are going to go through how to find your personal API key. ![](https://files.readme.io/c4d720c-mango_db_landing_page.png "mango_db_landing_page.png") Once you have logged in to MongoDB, you will be shown the home page of the MongoDB platform. ![](https://files.readme.io/b51fef5-clustor_page.png "clustor_page.png") Now go ahead and click on the **Database -> Clustor.** ![](https://files.readme.io/1c187f8-click_connect.png "click_connect.png") Click on Connect button. ![](https://files.readme.io/33559ad-select_mandoDB.png "select_mandoDB.png") Click Connect with the MangoDB Shell. ![](https://files.readme.io/504be5a-host_uname.png "host_uname.png") You should find the **host** and the **username**. ![](https://files.readme.io/113c676-DB_Access.png "DB_Access.png") Select **Database** from left side navigation. ![](https://files.readme.io/e12cf36-collections-db.png "collections-db.png") In **Collections** tab database name and information is given. ![](https://files.readme.io/4e03c80-database_access_edit.png "database_access_edit.png") Select **Database Access** from left-side navigation. Click on **Edit** button. ![](https://files.readme.io/2ec1b83-database_access_password.png "database_access_password.png") Click on Edit Password. ![](https://files.readme.io/814c68a-auto_generate-Secure_password.png "auto_generate-Secure_password.png") ![](https://files.readme.io/2ed2209-auto_generat_secure_password_01.png "auto_generat_secure_password_01.png") You can get the password by clicking \*\*Autogenerate Secure Password \*\*button. Click on \*\*Copy \*\*button to copy the password. You now have all the information Host, Username, password, database name and Auth Database that hotglue needs to connect to the MongoDB. # Montapacking Source: https://docs.hotglue.com/connectors/montapacking # Connector Details | Name | Value | | :- | :- | | Platform | [Montapacking](https://monta.nl) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-montapacking.git@v0](https://gitlab.com/hotglue/tap-montapacking.git@v0) | | Target Repo | [https://github.com/hotgluexyz/target-montapacking-v2](https://github.com/hotgluexyz/target-montapacking-v2) | | Tap Metrics | Usage: (high) Success Rate: (high) | | Target Metrics | Usage: (high) Success Rate: (high) | # Moosend Source: https://docs.hotglue.com/connectors/moosend # Connector Details | Name | Value | | :- | :- | | Platform | [Moosend](https://moosend.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-moosend](https://gitlab.com/hotglue/tap-moosend) | | Target Repo | [https://gitlab.com/hotglue/target-moosend](https://gitlab.com/hotglue/target-moosend) | | Tap Metrics | Usage: (low) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (high) | # Microsoft SQL Source: https://docs.hotglue.com/connectors/mssql # Connector Details | Name | Value | | :- | :- | | Platform | [Microsoft SQL](https://www.microsoft.com/en-us/sql-server) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-mssql](https://github.com/hotgluexyz/tap-mssql) | | Target Repo | [https://github.com/hotgluexyz/target-mssql](https://github.com/hotgluexyz/target-mssql) | | Tap Metrics | Usage: | | Target Metrics | Usage: | # Tap MSSQL ## Config `tap-mssql` requires the following connection parameters to be specified in the config: ```json theme={null} { "host": "your-server-hostname", "port": "1433", "database": "your_database", "user": "your_username", "password": "your_password" } ``` ## Example ETL Script ```python theme={null} import gluestick as gs import os # Define standard Hotglue directories ROOT_DIR = os.environ.get("ROOT_DIR", ".") INPUT_DIR = f"{ROOT_DIR}/sync-output" OUTPUT_DIR = f"{ROOT_DIR}/etl-output" # Read sync output input = gs.Reader() # Get tenant id tenant_id = os.environ.get('USER_ID', os.environ.get('TENANT', 'default')) # Iterate through the different streams in the sync output for key in eval(str(input)): input_df = input.get(key) """ Here we get the metadata for extracting the key properties, such as primary and replication keys. The database export targets will utilize these primary keys when upserting data. If you wish to hardcode your choice of primary keys, you can do so here. """ metadata = input.get_metadata(key) if metadata.get("key_properties"): # Use the key_properties (e.g. primary and replication keys) from the catalog key_properties = eval(metadata["key_properties"]) else: key_properties = [] # Include tenant_id as a field if desired input_df["tenant"] = tenant_id # Write this stream to the OUTPUT directory with the specified key_properties gs.to_singer(input_df, key, OUTPUT_DIR, keys=key_properties) ``` ## Optional config flags | Property | Description | Default | | - | - | - | | `dialect` | The SQLAlchemy dialect | `mssql` | | `driver_type` | The Python driver used to connect to SQL Server (`pymssql` or `pyodbc`) | `pymssql` | | `sqlalchemy_eng_params` | SQLAlchemy engine parameters (e.g., `fast_executemany`, `future`) | `None` | | `sqlalchemy_url_query` | SQLAlchemy URL query options passed through to ODBC | `None` | | `batch_config` | Optional batch message configuration | `None` | | `start_date` | The earliest record date to sync | `None` | | `hd_jsonschema_types` | Enable higher-defined JSON Schema types to assist targets | `false` | | `stream_maps` | Config object for stream maps capability | `None` | | `stream_map_config` | User-defined config values for map expressions | `None` | | `flattening_enabled` | Enable schema flattening and expand nested properties | `None` | | `flattening_max_depth` | The max depth to flatten schemas | `None` | | `lookback_window_days` | Number of past days to include when pulling data | `None` | ### The `sqlalchemy_url_query` Option When using `pyodbc` as the `driver_type`, you can pass ODBC-specific options. This is useful when connecting via Azure Active Directory or when certificate trust settings are required: ```json theme={null} { "host": "your-server-hostname", "database": "your_database", "user": "your_username", "password": "your_password", "driver_type": "pyodbc", "sqlalchemy_url_query": { "driver": "ODBC Driver 18 for SQL Server", "TrustServerCertificate": "yes", "Authentication": "ActiveDirectoryPassword" } } ``` ### The `sqlalchemy_eng_params` Option Enable `fast_executemany` to significantly reduce round trips to the server and improve bulk insert performance: ```json theme={null} { "host": "your-server-hostname", "database": "your_database", "user": "your_username", "password": "your_password", "sqlalchemy_eng_params": { "fast_executemany": "True" } } ``` ## Connecting to Microsoft Fabric Warehouse > [!NOTE] > > Use an **Entra service principal** to connect to Microsoft Fabric Warehouse — no username/password required. Follow the steps below to set up service principal authentication for Microsoft Fabric. ### 1. Register an app in Entra ID * Navigate to the [Azure Portal](https://portal.azure.com) and go to **Azure Active Directory** → **App registrations** → **New registration** * Give the app a name (e.g., `tap-mssql-fabric`) and select **Single tenant** * Click **Register** ### 2. Get your Client ID * On the app's **Overview** page, copy the **Application (client) ID** * This value will be used as `user` in the tap config ### 3. Create a client secret * Go to **Manage** → **Certificates & secrets** → **New client secret** * Add a description and choose an expiry period, then click **Add** * **Copy the secret Value immediately** — it is only shown once and will be used as `password` in the tap config > [!WARNING] > > If you lose the client secret value, you will need to create a new secret. ### 4. Grant the app access to Fabric * Open your workspace in [Microsoft Fabric](https://app.fabric.microsoft.com) * Add the app as a **member** with at minimum a **Viewer** role * Confirm the app has access to both the workspace and the specific database in your config ### 5. Get the warehouse host * In Microsoft Fabric, open your workspace and select the **Warehouse** * Go to **Settings** (gear icon) → **SQL Endpoint** * Copy the SQL connection string — it follows this format: `.datawarehouse.fabric.microsoft.com` ### Config for Fabric with Entra service principal ```json theme={null} { "dialect": "mssql", "driver_type": "pyodbc", "host": "your-warehouse.datawarehouse.fabric.microsoft.com", "database": "your_warehouse", "user": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "password": "your-client-secret-value", "sqlalchemy_url_query": { "driver": "ODBC Driver 18 for SQL Server", "Authentication": "ActiveDirectoryServicePrincipal" } } ``` *** # Target MSSQL `target-mssql` is a Singer Target that loads data from your integrations into a Microsoft SQL Server database. ## Config You can configure the target using one of two approaches: ### Option 1: Connection String Use a single connection string that includes all database details: ```json theme={null} { "sqlalchemy_url": "mssql+pyodbc://username:password@host:port/database?driver=ODBC+Driver+17+for+SQL+Server&Encrypt=yes&TrustServerCertificate=yes" } ``` > [!TIP] > > If your password contains special characters, URL-encode them (e.g., `@` becomes `%40`). ### Option 2: Individual Connection Parameters Specify each connection detail separately: ```json theme={null} { "user": "your_username", "password": "your_password", "host": "your-server-hostname", "port": "1433", "database": "your_database_name" } ``` | Parameter | Description | Example | | - | - | - | | `user` | Database username | `"sa"` or `"admin_user"` | | `password` | Database password | `"P@55w0rd"` | | `host` | Server hostname or IP address | `"localhost"` or `"sql.company.com"` | | `port` | SQL Server port (default: 1433) | `"1433"` | | `database` | Target database name | `"my_warehouse"` | ## Additional Settings | Setting | Description | Default | | - | - | - | | `default_target_schema` | Schema where tables will be created | `"dbo"` | | `truncate` | Drop and recreate all tables before loading (global) | `false` | | `input_path` | Directory containing per-stream configuration file | Not set | ## Per-Stream Configuration For advanced control over specific tables, create a `target-tables-config.json` in the directory specified by `input_path`. ```json theme={null} { "streams": { "users": { "truncate": true, "replication_method": "truncate" }, "orders": { "truncate": false, "replication_method": "merge" } } } ``` **Options per stream:** | Option | Description | | - | - | | `truncate` | Drop and recreate this specific table before loading | | `replication_method` | `"truncate"` replaces the entire table; `"merge"` upserts data using the primary key | ## Configuration Examples ### Basic Setup ```json theme={null} { "user": "sa", "password": "P@55w0rd", "host": "localhost", "port": "1433", "database": "mydatabase", "default_target_schema": "dbo" } ``` ### With Per-Stream Control ```json theme={null} { "user": "sa", "password": "P@55w0rd", "host": "localhost", "port": "1433", "database": "mydatabase", "input_path": "./etl-output" } ``` Then create `target-tables-config.json` in `./etl-output`: ```json theme={null} { "streams": { "customers": { "truncate": true }, "transactions": { "replication_method": "merge" } } } ``` # MYOB Source: https://docs.hotglue.com/connectors/myob # Connector Details | Name | Value | | :- | :- | | Platform | [MYOB](https://myob.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-myob](https://gitlab.com/hotglue/tap-myob) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # MySQL Source: https://docs.hotglue.com/connectors/mysql # Connector Details | Name | Value | | :- | :- | | Platform | [MySQL](https://mysql.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/transferwise/pipelinewise-tap-mysql](https://github.com/transferwise/pipelinewise-tap-mysql) | | Target Repo | [https://github.com/hotgluexyz/target-mysql-v2](https://github.com/hotgluexyz/target-mysql-v2) | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (medium) | # Target MySQL ## Config `target-mysql` requires the standard 5 connection parameters to be specified in the config: ```json theme={null} { "host": "https://...", "port": "3306", "user": "...", "password": "...", "database": "...", } ``` ## Example ETL Script ```python theme={null} import gluestick as gs import os # Define standard Hotglue directories ROOT_DIR = os.environ.get("ROOT_DIR", ".") INPUT_DIR = f"{ROOT_DIR}/sync-output" OUTPUT_DIR = f"{ROOT_DIR}/etl-output" # Read sync output input = gs.Reader() # Get tenant id tenant_id = os.environ.get('USER_ID', os.environ.get('TENANT', 'default')) # Iterate through the different streams in the sync output for key in eval(str(input)): input_df = input.get(key) """ Here we get the metadata for extracting the key properties, such as primary and replication keys. The database export targets will utilize these primary keys when upserting data. If you wish to hardcode your choice of primary keys, you can do so here. """ metadata = input.get_metadata(key) if metadata.get("key_properties"): # Use the key_properties (e.g. primary and replication keys) from the catalog key_properties = eval(metadata["key_properties"]) else: key_properties = [] # Include tenant_id as a field if desired input_df["tenant"] = tenant_id # Write this stream to the OUTPUT directory with the specified key_properties gs.to_singer(input_df, key, OUTPUT_DIR, keys=key_properties) ``` ## Optional config flags | Property | Description | Default | | - | - | - | | table\_name\_pattern | MySQL table name pattern to use when creating tables | "\$\{TABLE\_NAME}" | | lower\_case\_table\_names | Use lowercase for table names or not | true | | allow\_column\_alter | Allow column alterations or not | false | | replace\_null | Replace null values with others or not | false | | table\_config | Dictionary with specifications on insert/upsert/truncate | | ### The `replace_null` Option (Experimental) By enabling the `replace_null` option, null values are replaced with 'empty' equivalents based on their data type. Use with caution as it may alter data semantics. When `replace_null` is `true`, null values are replaced as follows: | JSON Schema Data Type | Null Value Replacement | | - | - | | string | Empty string(`""`) | | number | `0` | | object | Empty object(`{}`) | | array | Empty array(`[]`) | | boolean | `false` | | null | null | ### The `table_config` option By default, target-mysql will upsert your payload into each table. This means it will insert all new data into your table, but perform an update on primary key collision. The `table_config` allows you to override this behavior with one of two insertion methods: * `truncate`: Delete the existing table and replace it with the new data * `insert`: Attempt to insert all records as new rows, throwing an error on primary key collision If you want to use the `truncate` or `insert` methods, you can specify which tables should use the method using the `table_config` flag: ```json theme={null} { "host": "..." .... "table_config": { "accounts": "truncate", "vendors": "insert", } } ``` # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [1.6.0 (2024-05-09)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.6.0) | ## What's Changed \* Prefer SSL connection to source by @louis-pie in [https://github.com/transferwise/pipelinewise-tap-mysql/pull/181](https://github.com/transferwise/pipelinewise-tap-mysql/pull/181) **Full Changelog**: [https://github.com/transferwise/pipelinewise-tap-mysql/compare/v1.5.6...v1.6.0](https://github.com/transferwise/pipelinewise-tap-mysql/compare/v1.5.6...v1.6.0) | > | [1.5.6 (2023-08-10)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.5.6) | ## What's Changed \* AP-1531 Zero-pad fixed-length binary fields by @Samira-El in [https://github.com/transferwise/pipelinewise-tap-mysql/pull/162](https://github.com/transferwise/pipelinewise-tap-mysql/pull/162) **Full Changelog**: [https://github.com/transferwise/pipelinewise-tap-mysql/compare/v1.5.5...v1.5.6](https://github.com/transferwise/pipelinewise-tap-mysql/compare/v1.5.5...v1.5.6) | > | [1.5.5 (2023-07-05)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.5.5) | ## What's Changed \* LookupError: unknown encoding: utf8mb3 by @Samira-El in [https://github.com/transferwise/pipelinewise-tap-mysql/pull/163](https://github.com/transferwise/pipelinewise-tap-mysql/pull/163) \* Bump plpygis from 0.2.0 to 0.2.1 by @dependabot in [https://github.com/transferwise/pipelinewise-tap-mysql/pull/142](https://github.com/transferwise/pipelinewise-tap-mysql/pull/142) **Full Changelog**: [https://github.com/transferwise/pipelinewise-tap-mysql/compare/v1.5.4...v1.5.5](https://github.com/transferwise/pipelinewise-tap-mysql/compare/v1.5.4...v1.5.5) | > | [1.5.4 (2023-05-22)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.5.4) | ## What's Changed \* AP-1477: Bump python-mysql-replication by @Samira-El in [https://github.com/transferwise/pipelinewise-tap-mysql/pull/156](https://github.com/transferwise/pipelinewise-tap-mysql/pull/156) **Full Changelog**: [https://github.com/transferwise/pipelinewise-tap-mysql/compare/v1.5.3...v1.5.4](https://github.com/transferwise/pipelinewise-tap-mysql/compare/v1.5.3...v1.5.4) | > | [1.5.3 (2023-04-25)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.5.3) | \* LOG\_BASED: Set mariadb slave capability to 4 to mitigate bug in Mariadb 10.6.12 ([https://github.com/transferwise/pipelinewise-tap-mysql/pull/149](https://github.com/transferwise/pipelinewise-tap-mysql/pull/149)) | > | [1.5.2 (2022-08-12)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.5.2) | \* Bump mysql-replication to 0.30 | > | [1.5.1 (2022-04-05)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.5.1) | Fix: Handle case when BINLOG\_GTID\_POS returns multiple comma separated GTIDs | > | [1.5.0 (2022-03-11)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.5.0) | - Support logical replication using GTID, for both Mariadb & MySql - Log error message when session sqls fail - Bump depenedencies to support Mysql 8 - Migrate CI to Github Actions. | > | [1.4.3 (2021-04-09)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.4.3) | \* Fix in LOG\_BASED method: re-discovery constantly running when table has unsupported column type. \* Add support for tinytext column type \* Bump pendulum to 1.5.1 \* Add unit tests and re-arrange tests folder | > | [1.4.2 (2021-03-15)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.4.2) | Fixing typo introduced by a previous change. | > | [1.4.1 (2021-03-12)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.4.1) | Fix data loss during log\_based replication. | > | [1.4.0 (2020-11-09)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.4.0) | Support MySQL spatial types | > | [1.3.8 (2020-10-16)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.3.8) | Fix mapping bit to boolean values | > | [1.3.7 (2020-09-04)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.3.7) | Fix an issue with converting row to singer record where encountering a `time` type column causes the override of the whole row. | > | [1.3.6 (2020-09-02)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.3.6) | Fixed an issue when every extracted row was logged at `INFO` level and produced huge log files | > | [1.3.5 (2020-08-27)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.3.5) | Fix issue with `time` sql type not properly processed. Previously, it used to be turned into a datetime in the form of `1970-01-01 HH:MM:SS`, and now it's formatted to only be `HH:MM:SS` | > | [1.3.4 (2020-08-05)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.3.4) | Fix few issues with new discovered schema after changes are detected during LOG\_BASED runtime. | > | [1.3.3 (2020-07-23)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.3.3) | During LOG\_BASED runtime, detect new columns, incl renamed ones, by comparing the columns in the binlog event to the stream schema, and if there are any additional columns, run discovery and send a new SCHEMA message to target. This helps avoid data loss. | > | [1.3.2 (2020-06-15)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.3.2) | - Revert `pymysql` back to `0.7.11`. `pymysql >= 0.8.1` introducing some not expected and not backward compatible changes how it's dealing with invalid datetime columns. | > | [1.3.1 (2020-06-15)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.3.1) | - Fix dependency issue by removing `attrs` from `setup.py` - Bump `pymysql` to `0.9.3` | > | [1.3.0 (2020-05-18)](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.3.0) | - Add optional `session_sqls` connection parameter - Support `JSON` column types | > | [Make logging customizable](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.2.0) | | > | [Update bookmark only if binlog position is valid](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.1.5) | | > | [Update bookmark when reading bookmark finished](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.1.4) | | > | [Update bookmark only before writing state message](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.1.3) | | > | [Handle null bytes in Binary type columns using SQL](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.1.2) | | > | [Handle padding 0s in Binary type columns](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.1.1) | | > | [ Support binary and varbinary columns](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.1.0) | | > | [Upgrade mysql-replication package](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.0.7) | | > | [Add license classifier](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.0.6) | | > | [Remove BINARY and VARBINARY support](https://github.com/transferwise/pipelinewise-tap-mysql/releases/tag/v1.0.5) | | # Netohq Source: https://docs.hotglue.com/connectors/netohq # Connector Details | Name | Value | | :- | :- | | Platform | [Netohq](https://netohq.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-netohq](https://gitlab.com/hotglue/tap-netohq) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # NetSuite Source: https://docs.hotglue.com/connectors/netsuite # Connector Details | Name | Value | | :- | :- | | Platform | [NetSuite](https://NetSuite.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-netsuite-rest](https://github.com/hotgluexyz/tap-netsuite-rest) | | Target Repo | [https://github.com/hotgluexyz/target-netsuite-v2](https://github.com/hotgluexyz/target-netsuite-v2) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (low) | | Unified Schema | Supported in [Accounting Unified Schema](https://hotglue.com/docs/unified). (Supported tables: Customers, Items, SalesOrders, Accounts, Vendors, Classes, BankAccounts, Projects, JournalEntries) | # Credentials Setup Follow the steps below to get the credentials you need to use the NetSuite connector. **Step 1** #### Step 1: Create a new Integration in NetSuite. Head to Setup > Integration > Manage Integrations > New. ![](https://mintcdn.com/hotglue/vhf7LyqSF85g3EeZ/connectors/images/NetSuiteIntegrationBreadcrumb.png?fit=max\&auto=format\&n=vhf7LyqSF85g3EeZ\&q=85\&s=58c551cb9f8bcd00286c6158f0d96262) Now fill out the fields as shown. * Choose an integration name of your choice. * You must select Token Based Authentication and TBA: Issuetoken Endpoint * You must NOT select Authorization Code Grant ![](https://mintcdn.com/hotglue/vhf7LyqSF85g3EeZ/connectors/images/NetSuiteIntegrationFields.png?fit=max\&auto=format\&n=vhf7LyqSF85g3EeZ\&q=85\&s=1f2517e2b80930ed13c817031997826b) Save your NetSuite Consumer Key and NetSuite Consumer Secret. ![](https://mintcdn.com/hotglue/74wwvCK2_tOM1rGf/connectors/images/NetSuiteConsumerToken.png?fit=max\&auto=format\&n=74wwvCK2_tOM1rGf\&q=85\&s=bd8478998dbf46744ad3407416e7327c) **Step 2** #### Step 2A (Easy): Create a NetSuite Role with the appropriate permissions. This is the easiest way to setup a NetSuite Role with the appropriate permissions for Hotglue. Head to Customization > SuiteBundler > Search & Install Bundles ![](https://mintcdn.com/hotglue/vhf7LyqSF85g3EeZ/connectors/images/NetSuiteFindBundleSetting.png?fit=max\&auto=format\&n=vhf7LyqSF85g3EeZ\&q=85\&s=a77223afa19d407304cbe7c4b5788550) Type in 572067 (*or 572066*) as your keyword, hit the search button, and select the Hotglue (read-only) (*or Hotglue (read+write)*) role. > [!NOTE] > > If you want write permission given to Hotglue, you can type in 572066. Make sure the package says *Hotglue (read+write).* ![](https://mintcdn.com/hotglue/vhf7LyqSF85g3EeZ/connectors/images/NetSuiteSearchBundle.png?fit=max\&auto=format\&n=vhf7LyqSF85g3EeZ\&q=85\&s=23f5844b5a9656609a97d6bcf92412bf) Install the bundle. ![](https://mintcdn.com/hotglue/vhf7LyqSF85g3EeZ/connectors/images/NetSuiteInstallBundle.png?fit=max\&auto=format\&n=vhf7LyqSF85g3EeZ\&q=85\&s=9842f7a28a9d508e673811bca82b1bd8) Your role name for Step 3 will now be Hotglue (read-only) or Hotglue (read+write). [Go to Step 3](#step-3-assign-netsuite-role-to-netsuite-user) #### Step 2B (Hard): Create a NetSuite Role with the appropriate permissions. It is recommended that you follow [Step 2A (Easy)](#step-2a-easy-%3A-create-a-netsuite-role-with-the-appropriate-permissions): Head to Setup > Users/Roles > Manage Roles > New ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgS4edRA2VPrc8lwwPd%2F-MgSDTkpLhFRJZEMP0Gx%2Fnetsuite-roles.gif?alt=media\&token=11f73a5f-8cfd-4931-a67d-5e93b22f210b) Choose a new role name of your choice and go to Permissions - Setup on the bottom of the page. ![](https://mintcdn.com/hotglue/74wwvCK2_tOM1rGf/connectors/images/NetSuiteRolesSetupStart.png?fit=max\&auto=format\&n=74wwvCK2_tOM1rGf\&q=85\&s=d8202cc0d508c3490a775fd685e1aa82) Now add the following permissions: * User Access Token (Full) * SOAP Web Services (Full) * Log in using Access Tokens (Full) * Integration Application (Full) * REST Web Services (Full) * Access Token Management (Full) ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgS4edRA2VPrc8lwwPd%2F-MgSF_vlrjDw9b-H3sg2%2Fimage.png?alt=media\&token=a2c1b072-4b31-470b-b584-fedaab712aee) Add the permissions you need to access relevant data in the Transactions, Reports, and Lists sections. See a full list of available objects in the [NetSuite docs](https://www.NetSuite.com/help/helpcenter/en_US/srbrowser/Browser2016_1/schema/record/account.html)​ ![](https://mintcdn.com/hotglue/vhf7LyqSF85g3EeZ/connectors/images/NetSuiteAddNecessaryPerms.png?fit=max\&auto=format\&n=vhf7LyqSF85g3EeZ\&q=85\&s=5f30e64dbd18dd263daa9f2d3ae3fa8b) Hit the save button. **Step 3** #### Step 3: Assign NetSuite Role to NetSuite User If you want to assign the Integration Token a New User, head to Lists > Employees > Employees > New ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgS4edRA2VPrc8lwwPd%2F-MgSH2j_GxiUZsE1YznZ%2Fimage.png?alt=media\&token=5ec404df-163d-4a52-a36a-00f030fafc3a) Alternatively, if you already have a User you'd like to use ready, head to Lists > Employees > Employees > Search and open the user. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgS4edRA2VPrc8lwwPd%2F-MgSHpc3MnrnmPQe54S7%2Fimage.png?alt=media\&token=6241693b-9b27-4069-a5c4-da5e09c3abdc) Once you have opened the relevant user, and select Edit ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgS4edRA2VPrc8lwwPd%2F-MgSINsMtVU4HwDKVRf-%2Fimage.png?alt=media\&token=94a516d6-2c90-44a3-a27e-44722374e724) Edit Employee Scroll down to the Access > Roles tab, and add our new Integration Role to the list ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgS4edRA2VPrc8lwwPd%2F-MgSJLLFpj4Mt1RCorQq%2Fimage.png?alt=media\&token=70a32a26-7885-4fac-92f8-45b77af929a0) Add Integration Role to User Press Save **Step 4** #### Step 4: Generate NetSuite Access Token / Secret Head to Setup > Users/Roles > Access Tokens > New ![](https://mintcdn.com/hotglue/vhf7LyqSF85g3EeZ/connectors/images/NetSuiteAccessTokenBreadcrumb.png?fit=max\&auto=format\&n=vhf7LyqSF85g3EeZ\&q=85\&s=ab9a8bcf5da8403eead8995d722a2155) On the Access Token page, select the Integration Record (Application Name), User, and Role we just setup. ![](https://mintcdn.com/hotglue/vhf7LyqSF85g3EeZ/connectors/images/NetSuiteFillAccessTokenOptions.png?fit=max\&auto=format\&n=vhf7LyqSF85g3EeZ\&q=85\&s=b2f2f4b0c587b248552872b81c6c325b) Once configured, press Save. You will see your NetSuite Token ID (Key) / Secret at the bottom of the page: ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MgS4edRA2VPrc8lwwPd%2F-MgSLXG_ObTgYTaAFwQc%2Fimage.png?alt=media\&token=dd6e16e3-9463-4234-b7d4-373d7cfe61f6) **Step 5** #### Step 5: Add the credentials to Hotglue We're done! You're ready to use the NetSuite integration in Hotglue. To find your account ID, you can either search NetSuite for Account ID, or you can take the first number in your URL for NetSuite. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.5.20](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.20) | | > | [v1.5.19](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.19) | | > | [v1.5.18](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.18) | | > | [v1.5.17](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.17) | | > | [v1.5.16](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.16) | | > | [v1.5.15](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.15) | | > | [v1.5.14](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.14) | | > | [v1.5.13](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.13) | | > | [v1.5.12](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.12) | | > | [v1.5.11](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.11) | - Update replicate key logic | > | [v1.5.10](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.10) | - Fix replication keys issues | > | [v1.5.9](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.9) | | > | [v1.5.8 - Add support for discount lines](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.8) | - Add support for discount lines in `Invoices` | > | [v1.5.7 - Add backoff handling](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.7) | - Add backoff handling in NetSuite SDK to handle gateway timeouts and concurrent request exceptions | > | [v1.5.6 - Bump NetSuite sdk](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.6) | - Bumped NetSuite sdk version | > | [v1.5.5 - Handle empty data error](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.5) | - Handle error when there's no data for a stream | > | [v1.5.4 - Fix Item schema issue](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.4) | - Updated `rate` schema to `string` instead of `number` | > | [v1.5.3 - Add support for Purchase Orders](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.3) | - Added support for Purchase Orders | > | [v1.5.1 – Add SalesOrder support](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.1) | Added support for pulling Sales Orders and added `internalid` to payloads | > | [v1.5.0 – Fix issue with duplicate columns in output](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.5.0) | - Fixed schema issue causing duplicate `LastModDate` entry in the output for `InventoryItem` | > | [v1.4.33 - Hotfix for pulling Vendor Payments and Vendor Bills](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.4.33) | Fixed bug pulling Vendor Payments and Vendor Bills which was caused by updating NetSuite SDK | > | [v1.4.32 - Add support for inventory management endpoints](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.4.32) | Added support for inventory management endpoints | > | [v1.4.31](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.4.31) | Update issue with `replication_key_value` missing assignment | > | [v1.4.30](https://github.com/hotgluexyz/tap-NetSuite/releases/tag/v1.4.30) | Add support for Vendors, VendorBills, VendorPayments, and Invoices | # Newmode Source: https://docs.hotglue.com/connectors/newmode # Connector Details | Name | Value | | :- | :- | | Tap Repo | [https://github.com/hotgluexyz/tap-newmode](https://github.com/hotgluexyz/tap-newmode) | | Target Repo | [https://github.com/hotgluexyz/target-newmode](https://github.com/hotgluexyz/target-newmode) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| | Target Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| # Notion Source: https://docs.hotglue.com/connectors/notion # Connector Details | Name | Value | | :- | :- | | Platform | [Notion](https://notion.so) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-notion](https://github.com/hotgluexyz/tap-notion) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Odoo Source: https://docs.hotglue.com/connectors/odoo # Connector Details | Name | Value | | :- | :- | | Platform | [Odoo](https://odoo.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-odoo](https://gitlab.com/hotglue/tap-odoo) | | Target Repo | [https://github.com/hotgluexyz/target-odoo-v3](https://github.com/hotgluexyz/target-odoo-v3) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (high) | # Omnisend Source: https://docs.hotglue.com/connectors/omnisend # Connector Details | Name | Value | | :- | :- | | Platform | [Omnisend](https://omnisend.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-omnisend](https://gitlab.com/hotglue/tap-omnisend) | | Tap Metrics | Usage: (medium) Success Rate: (high) | # Ongoing WMS Source: https://docs.hotglue.com/connectors/ongoing # Connector Details | Name | Value | | :- | :- | | Platform | [Ongoing WMS](https://ongoingwarehouse.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-ongoing](https://github.com/hotgluexyz/tap-ongoing) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Ongoing WMS connector. ## Goods Owner ID, API Username, and API Password The first thing you need to do is log in to Ongoing WMS. ![](https://files.readme.io/2877706-Screen_Shot_2022-02-16_at_3.38.14_PM.png "Screen Shot 2022-02-16 at 3.38.14 PM.png") Your home page should look something like this. On the top left side of your screen, you should click the Applications option from the navigation menu. ![](https://files.readme.io/07b53c1-Screen_Shot_2022-02-16_at_3.58.03_PM.png "Screen Shot 2022-02-16 at 3.58.03 PM.png") Now, you should select the API for goods owners option. ![](https://files.readme.io/f7e8b46-Screen_Shot_2022-02-16_at_4.17.57_PM.png "Screen Shot 2022-02-16 at 4.17.57 PM.png") On this page, you will see your Goods owners. For this example, I am going to use the hotglue testing owner. As you can see, the Goods owner ID is on the left hand side. This is one of the credentials you will need for hotglue! Go ahead and copy it into hotglue. Once you have done that, you need to make sure the API is enabled for that specific user. If there is a check mark in the **Has API access** column, then it is already done. If it is not checked off, click the down arrow. ![](https://files.readme.io/1599fd4-Screen_Shot_2022-02-16_at_4.12.02_PM.png "Screen Shot 2022-02-16 at 4.12.02 PM.png") If the API access has not been enabled, go ahead and click Allow API access. ![](https://files.readme.io/03ea388-Screen_Shot_2022-02-16_at_4.14.26_PM.png "Screen Shot 2022-02-16 at 4.14.26 PM.png") You should now fill out this form. Make sure you copy the credentials from your Username and Password into hotglue. ![](https://files.readme.io/52c2e02-Screen_Shot_2022-02-16_at_4.14.53_PM.png "Screen Shot 2022-02-16 at 4.14.53 PM.png") Once you have filled out this form, click create! ![](https://files.readme.io/82937f6-Screen_Shot_2022-02-16_at_4.18.48_PM.png "Screen Shot 2022-02-16 at 4.18.48 PM.png") You will now be able to see the related User ID that you need to put into hotglue as well. Make sure to mark it down! ![](https://files.readme.io/68851ef-Screen_Shot_2022-02-16_at_4.23.18_PM.png "Screen Shot 2022-02-16 at 4.23.18 PM.png") ## Warehouse name The last thing you will need is the Warehouse you are looking to connect. To find the name, head to the Warehouses section of your account. ![](https://files.readme.io/3e16c76-Screen_Shot_2022-02-16_at_4.25.54_PM.png "Screen Shot 2022-02-16 at 4.25.54 PM.png") Now go ahead and grab the name of whichever Warehouse you want to connect in hotglue. For this example, we are going to choose the hotglueWarehouse. And that is it! You now have all of your credentials. # Open Exchange Rates Source: https://docs.hotglue.com/connectors/openexchangerates # Connector Details | Name | Value | | :- | :- | | Platform | [Open Exchange Rates](https://openexchangerates.org) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-openexchangerates](https://gitlab.com/hotglue/tap-openexchangerates) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Ordoro Source: https://docs.hotglue.com/connectors/ordoro # Connector Details | Name | Value | | :- | :- | | Platform | [Ordoro](https://ordoro.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-ordoro](https://gitlab.com/hotglue/tap-ordoro) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Outreach Source: https://docs.hotglue.com/connectors/outreach # Connector Details | Name | Value | | :- | :- | | Platform | [Outreach](https://outreach.io) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-outreach](https://gitlab.com/hotglue/tap-outreach) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # PagerDuty Source: https://docs.hotglue.com/connectors/pagerduty # Connector Details | Name | Value | | :- | :- | | Platform | [PagerDuty](https://pagerduty.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-pagerduty](https://github.com/hotgluexyz/tap-pagerduty) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the PagerDuty connector. The first thing you must do is [log in to PagerDuty](https://app.pagerduty.com). ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MhP2tsKb5laiq2WXbxR%2F-MhP3meAOpRv_t5QTo4u%2FScreen%20Shot%202021-08-18%20at%2012.22.02%20PM.png?alt=media\&token=9fb241cc-fbb7-4347-a69a-b29a230f03ad) Now that you have logged in, go ahead and click on the Integrations tab on the top of the page. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MhP4505aSuH1UKM_Rb4%2F-MhP4D4PC0mDuUjmqG2k%2FScreen%20Shot%202021-08-18%20at%2012.25.00%20PM.png?alt=media\&token=7cf53d9c-01e0-46a9-b51d-ba48f30f2e69) From the resulting drop down, you are going to want to select the API Access Keys option. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MhP6u8GBZv0vmhWPrb_%2F-MhP83tiBDiaq7voyOHp%2FScreen%20Shot%202021-08-18%20at%2012.40.15%20PM.png?alt=media\&token=89b38d10-9e59-45d5-ada9-aef08657cbe5) If you already have created your API Key, you will be able to find it here. If you have not made your API Key yet, start by clicking the Create New API Key button. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MhPAVYmiwnksbDuCWC3%2F-MhPDLKmKt_KJ0mTIIC0%2FScreen%20Shot%202021-08-18%20at%201.04.47%20PM.png?alt=media\&token=b374f50e-76b8-49e6-84b7-b4979d4858a5) Now you should input the description of the key and click Create Key. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MhPDX_uirb5mm-rMi2D%2F-MhPDnR73LIus4T5tNva%2FScreen%20Shot%202021-08-18%20at%201.06.36%20PM.png?alt=media\&token=c348cef0-ef72-4e63-a9ea-b0244c91d0eb) Now you have your API key. Don't forget to put it in hotglue! :) # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.1.2 - Add support for Users Stream](https://github.com/hotgluexyz/tap-pagerduty/releases/tag/v0.1.2) | Add support for pulling users: [https://developer.pagerduty.com/api-reference/reference/REST/openapiv3.json/paths/\~1users/get](https://developer.pagerduty.com/api-reference/reference/REST/openapiv3.json/paths/~1users/get) | # Parquet Source: https://docs.hotglue.com/connectors/parquet # Connector Details | Name | Value | | :- | :- | | Target Repo | [https://github.com/hotgluexyz/target-parquet](https://github.com/hotgluexyz/target-parquet) | # PayPal Source: https://docs.hotglue.com/connectors/paypal # Connector Details | Name | Value | | :- | :- | | Platform | [PayPal](https://paypal.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-paypal](https://gitlab.com/hotglue/tap-paypal) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Picqer Source: https://docs.hotglue.com/connectors/picqer # Connector Details | Name | Value | | :- | :- | | Platform | [Picqer](https://picqer.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-picqer](https://gitlab.com/hotglue/tap-picqer) | | Target Repo | [https://gitlab.com/hotglue/target-picqer](https://gitlab.com/hotglue/target-picqer) | | Tap Metrics | Usage: (low) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (high) | | Target Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| # Pipedrive Source: https://docs.hotglue.com/connectors/pipedrive # Connector Details | Name | Value | | :- | :- | | Platform | [Pipedrive](https://pipedrive.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Triggers | Supported (3 triggers available by default) | | Tap Repo | [https://github.com/hotgluexyz/tap-pipedrive](https://github.com/hotgluexyz/tap-pipedrive) | | Target Repo | [https://gitlab.com/hotglue/target-pipedrive](https://gitlab.com/hotglue/target-pipedrive) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (low) | | Unified Schema | Supported in [Sales Unified Schema](https://hotglue.com/docs/unified). (Supported tables: Contacts, Deals, Companies, Activities, Users, Pipelines, Stages, Notes, Products) | # Credentials Setup Follow the steps below to get the credentials you need to use the Pipedrive connector. All you need to begin integrating with Pipedrive is an OAuth app and a sandbox account. Both are free through [Pipedrive's developer program](https://developers.pipedrive.com/). You are also welcome to use hotglue's OAuth app to test. Once you have an account, head over to Pipedrive's [developer hub](https://app.pipedrive.com/developer-hub) to create an OAuth app. ![](https://files.readme.io/e62d461-pipe-05.png "pipe-05.png") 1. Click "Create new app". You can use a private app to test, but you will eventually need to create a public app for your customers. 2. Name your app with your business name, and set your callback URL as `https://hotglue.xyz/callback` 3. Set your scopes. This will vary depending on the data you expect to utilize, but **See Recent Account Activity** will always be needed. Let us know if you need help figuring out what these need to be. 4. Click save. Below the scopes you will find your Client ID and secret. Paste these into hotglue. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.1.6](https://github.com/hotgluexyz/tap-pipedrive/releases/tag/v1.1.6) | | > | [v1.1.5](https://github.com/hotgluexyz/tap-pipedrive/releases/tag/v1.1.5) | | > | [v1.1.4](https://github.com/hotgluexyz/tap-pipedrive/releases/tag/v1.1.4) | clean up custom fields in catalog | > | [v1.1.3](https://github.com/hotgluexyz/tap-pipedrive/releases/tag/v1.1.3) | Bug fixes | > | [v1.1.2](https://github.com/hotgluexyz/tap-pipedrive/releases/tag/v1.1.2) | | > | [v1.1.1](https://github.com/hotgluexyz/tap-pipedrive/releases/tag/v1.1.1) | | # plentymarkets Source: https://docs.hotglue.com/connectors/plentymarkets # Connector Details | Name | Value | | :- | :- | | Platform | [plentymarkets](https://plentymarkets.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-plentymarkets](https://gitlab.com/hotglue/tap-plentymarkets) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # PostgreSQL Source: https://docs.hotglue.com/connectors/postgres # Connector Details | Name | Value | | :- | :- | | Platform | [PostgreSQL](https://postgresql.org) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-postgres](https://gitlab.com/hotglue/tap-postgres) | | Target Repo | [https://github.com/hotgluexyz/pipelinewise-target-postgres](https://github.com/hotgluexyz/pipelinewise-target-postgres) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (high) | # Target Postgres ## Config `target-postgres` requires the standard 6 connection parameters to be specified in the config: ```json theme={null} { "host": "https://...", "port": "5432", "user": "...", "password": "...", "dbname": "...", "default_target_schema": "public" } ``` ## Example ETL Script ```python theme={null} import gluestick as gs import os # Define standard Hotglue directories ROOT_DIR = os.environ.get("ROOT_DIR", ".") INPUT_DIR = f"{ROOT_DIR}/sync-output" OUTPUT_DIR = f"{ROOT_DIR}/etl-output" # Read sync output input = gs.Reader() # Get tenant id tenant_id = os.environ.get('USER_ID', os.environ.get('TENANT', 'default')) # Iterate through the different streams in the sync output for key in eval(str(input)): input_df = input.get(key) """ Here we get the metadata for extracting the key properties, such as primary and replication keys. The database export targets will utilize these primary keys when upserting data. If you wish to hardcode your choice of primary keys, you can do so here. """ metadata = input.get_metadata(key) if metadata.get("key_properties"): # Use the key_properties (e.g. primary and replication keys) from the catalog key_properties = eval(metadata["key_properties"]) else: key_properties = [] # Include tenant_id as a field if desired input_df["tenant"] = tenant_id # Write this stream to the OUTPUT directory with the specified key_properties gs.to_singer(input_df, key, OUTPUT_DIR, keys=key_properties) ``` ## Optional config flags | Property | Type | Description | | - | - | - | | ssl | Boolean | (Default: False) Enable SSL for the connection to Postgres. | | insertion\_method | String | (Default: 'incremental') Currently only handles 'truncate' (drop and re-create table before adding rows) and 'incremental' (upsert new rows) | | batch\_size\_rows | Integer | (Default: 100000) Maximum number of rows in each batch. At the end of each batch, the rows in the batch are loaded into Postgres. | | flush\_all\_streams | Boolean | (Default: False) Flush and load every stream into Postgres when one batch is full. Warning: This may trigger the COPY command to use files with low number of records. | | parallelism | Integer | (Default: 0) The number of threads used to flush tables. 0 will create a thread for each stream, up to parallelism\_max. -1 will create a thread for each CPU core. Any other positive number will create that number of threads, up to parallelism\_max. | | max\_parallelism | Integer | (Default: 16) Max number of parallel threads to use when flushing tables. | | default\_target\_schema | String | Name of the schema where the tables will be created. If `schema_mapping` is not defined then every stream sent by the tap is loaded into this schema. | | default\_target\_schema\_select\_permission | String | Grant USAGE privilege on newly created schemas and grant SELECT privilege on newly created | | schema\_mapping | Object | Useful if you want to load multiple streams from one tap to multiple Postgres schemas. If the tap sends the `stream_id` in `-` format then this option overwrites the `default_target_schema` value. Note, that using `schema_mapping` you can overwrite the `default_target_schema_select_permission` value to grant SELECT permissions to different groups per schemas or optionally you can create indices automatically for the replicated tables. **Note**: This is an experimental feature and recommended to use via PipelineWise YAML files that will generate the object mapping in the right JSON format. For further info check a [PipelineWise YAML Example](https://transferwise.github.io/pipelinewise/connectors/taps/mysql.html#configuring-what-to-replicate). | | add\_metadata\_columns | Boolean | (Default: False) Metadata columns add extra row level information about data ingestions, (i.e. when was the row read in source, when was inserted or deleted in postgres etc.) Metadata columns are creating automatically by adding extra columns to the tables with a column prefix `_SDC_`. The column names are following the stitch naming conventions documented at [https://www.stitchdata.com/docs/data-structure/integration-schemas#sdc-columns](https://www.stitchdata.com/docs/data-structure/integration-schemas#sdc-columns). Enabling metadata columns will flag the deleted rows by setting the `_SDC_DELETED_AT` metadata column. Without the `add_metadata_columns` option the deleted rows from singer taps will not be recognisable in Postgres. | | hard\_delete | Boolean | (Default: False) When `hard_delete` option is true then DELETE SQL commands will be performed in Postgres to delete rows in tables. It's achieved by continuously checking the `_SDC_DELETED_AT` metadata column sent by the singer tap. Due to deleting rows requires metadata columns, `hard_delete` option automatically enables the `add_metadata_columns` option as well. | | data\_flattening\_max\_level | Integer | (Default: 0) Object type RECORD items from taps can be transformed to flattened columns by creating columns automatically. When value is 0 (default) then flattening functionality is turned off. | | primary\_key\_required | Boolean | (Default: True) Log based and Incremental replications on tables with no Primary Key cause duplicates when merging UPDATE events. When set to true, stop loading data if no Primary Key is defined. | | validate\_records | Boolean | (Default: False) Validate every single record message to the corresponding JSON schema. This option is disabled by default and invalid RECORD messages will fail only at load time by Postgres. Enabling this option will detect invalid records earlier but could cause performance degradation. | | temp\_dir | String | (Default: platform-dependent) Directory of temporary CSV files with RECORD messages. | | insertion\_method\_tables | Array(String) | (Default: \[]) Tables to apply "insertion method" to. Has no effect if insertion method not specified. | # Target Changelog > [accordion] Target Changelog > > | Version | Notes | > | :- | :- | > | [v0.3.0](https://github.com/hotgluexyz/target-postgres/releases/tag/v0.3.0) | | > | [v0.2.6](https://github.com/hotgluexyz/target-postgres/releases/tag/v0.2.6) | | > | [v0.2.5](https://github.com/hotgluexyz/target-postgres/releases/tag/v0.2.5) | - Switch to using psycog2 binary | # PostHog Source: https://docs.hotglue.com/connectors/posthog # Connector Details | Name | Value | | :- | :- | | Platform | [PostHog](https://posthog.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-posthog](https://gitlab.com/hotglue/tap-posthog) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the PostHog connector. Inside your project in PostHog, Click on the login-in name at top right. ![](https://files.readme.io/eac497b-image.png) Select the settings icon to navigate to the settings page. ![](https://files.readme.io/efe8da6-image.png) Scroll down the page and create a new Personal API key. Now you can insert API Secret into your hotglue PostHog source settings: # PowerBI Source: https://docs.hotglue.com/connectors/powerbi # Connector Details | Name | Value | | :- | :- | | Platform | [PowerBI](https://powerbi.microsoft.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-powerbi](https://gitlab.com/hotglue/tap-powerbi) | | Target Repo | [https://gitlab.com/hotglue/target-powerbi](https://gitlab.com/hotglue/target-powerbi) | | Tap Metrics | Usage: (medium) Success Rate: (high) | | Target Metrics | Usage: (medium) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the PowerBI connector. [https://www.loom.com/embed/bcf36d961c84451695b257467a19c9c2?sid=5f02fff7-1501-475c-8806-236c16209724](https://www.loom.com/embed/bcf36d961c84451695b257467a19c9c2?sid=5f02fff7-1501-475c-8806-236c16209724) # Precoro Source: https://docs.hotglue.com/connectors/precoro # Connector Details | Name | Value | | :- | :- | | Platform | [Precoro](https://precoro.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-precoro](https://github.com/hotgluexyz/tap-precoro) | | Target Repo | [https://github.com/hotgluexyz/target-precoro](https://github.com/hotgluexyz/target-precoro) | | Tap Metrics | Usage: (high) Success Rate: (high) | | Target Metrics | Usage: (medium) Success Rate: (high) | # PrestaShop Source: https://docs.hotglue.com/connectors/prestashop # Connector Details | Name | Value | | :- | :- | | Platform | [PrestaShop](https://prestashop.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-prestashop](https://gitlab.com/hotglue/tap-prestashop) | | Tap Metrics | Usage: (low) | # Procore Source: https://docs.hotglue.com/connectors/procore # Connector Details | Name | Value | | :- | :- | | Platform | [Procore](https://procore.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-procore](https://github.com/hotgluexyz/tap-procore) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Procore connector. In this section, you will learn how to get your OAuth credentials from Procore. First thing you must do is log in to their [developer portal](https://developers.procore.com). ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-Mfhd_2BVqFGWqLZcQlZ%2F-MfhdoSj1vR7_NdDnrz7%2FScreen%20Shot%202021-07-28%20at%2011.06.12%20AM.png?alt=media\&token=5831fb93-194b-4c93-8876-5ef041808544) Once you log in, you will see this page. You should click the Create A New App option. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-Mfhdq_y0sjMjMP5nSYw%2F-Mfhems0oRiFjrkZXE74%2FScreen%20Shot%202021-07-28%20at%2011.10.23%20AM.png?alt=media\&token=24f918fd-7cb5-4eff-9681-407ce495761d) Next, you should name your app accordingly. We suggest "company-name app". Then, click the Create button. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-Mfhdq_y0sjMjMP5nSYw%2F-Mfhf75Obiv_h5KQJkP3%2FScreen%20Shot%202021-07-28%20at%2011.12.16%20AM.png?alt=media\&token=354942cc-dea4-43c1-8fb7-5dfac476ced0) You will now be taken to this page. You will most likely have to wait a few minutes for Procore to finish setting up your sandbox. In the mean time, upload your logo for the App Avatar section on the page. Once you wait about 5 minutes, go ahead and refresh the page. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-Mfhdq_y0sjMjMP5nSYw%2F-Mfhfs_R6-j_w0Y5ZDkV%2FScreen%20Shot%202021-07-28%20at%2011.15.37%20AM.png?alt=media\&token=98024fd5-b857-4102-8768-004822c8e7d6) The next thing you should do is click Create New Version under Manage Manifests. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MfhhhFkwPdvX-xa2_Xm%2F-MfhjIDKy-31BQLgNNd2%2FScreen%20Shot%202021-07-28%20at%2011.30.30%20AM.png?alt=media\&token=8819dd69-e695-4875-acd5-690bb00e9878) Follow the instructions given, and once you are finished, click the Create button. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-Mfhk-qEnAxepgBX-7Hn%2F-MfhkPHj4uXtK03WkC9z%2FScreen%20Shot%202021-07-28%20at%2011.34.53%20AM.png?alt=media\&token=ee60f2aa-aae7-4822-8427-be66c669ad8c) You will now be able to see your OAuth Client ID and Client Secret for your app. Make sure that for the Redirect URL, you put ```text theme={null} https://hotglue.xyz/callback ``` And that is it! You now have your credentials to start using the Procore credenitials in hotglue. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.11 - Add Purchase Orders support](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.11) | - Added support for pulling Purchase Orders | > | [v0.0.10 - Fix subfolder processing](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.10) | Fix bug with `company_id` missing on subfolders | > | [v0.0.9 - Handle Procore-Company-Id header](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.9) | Meet requirement for production level Procore integrations to include a `Procore-Company-Id` header in each request. | > | [v0.0.8 - Handle refresh\_tokens correctly in prod](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.8) | Fixes to handle production Procore accounts correctly | > | [v0.0.7 - Add support for files in root directory](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.7) | Now supports pulling documents in the root project directory | > | [0.0.6 - Add `project_id` to stream response](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.6) | Add `project_id` to stream response | > | [v0.0.5 - Add Users Stream](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.5) | Added `Users` stream which includes all Project Members from Procore | > | [v0.0.4 - Add ProjectRoles stream](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.4) | Added ProjectRoles stream to tap | > | [v0.0.3 - Remove catalog config](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.3) | Remove catalog config... again | > | [v0.0.2 - Hot Fix](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.2) | Currently only works if all streams are selected in catalog | > | [v0.0.1 - Initial version](https://github.com/hotgluexyz/tap-procore/releases/tag/v0.0.1) | Singer tap for Procore built on Meltano's Singer SDK | # PropX Source: https://docs.hotglue.com/connectors/propx # Connector Details | Name | Value | | :- | :- | | Platform | [PropX](https://propx.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-propx](https://gitlab.com/hotglue/tap-propx) | | Tap Metrics | Usage: (medium) Success Rate: (high) | # QuickBooks Web Connector Source: https://docs.hotglue.com/connectors/qbwc # Connector Details | Name | Value | | :- | :- | | Platform | [QuickBooks Desktop](https://quickbooks.intuit.com/desktop/) | | Auth Type | On-Premise (QuickBooks Web Connector) | | Direction | Bidirectional | # Overview The [QuickBooks Web Connector (QBWC)](https://developer.intuit.com/app/developer/qbdesktop/docs/get-started/get-started-with-quickbooks-web-connector) is a Windows application from Intuit that ships with QuickBooks Desktop. It acts as a bridge between a QuickBooks company file and a web service: on a schedule you configure, QBWC contacts hotglue, picks up any pending read or write requests, runs them against the company file, and sends the results back. Compared to the [installed QuickBooks Desktop connector](/connectors/quickbooks-desktop): * **Nothing to install from hotglue.** Your tenant only needs a `.qwc` configuration file and a connector password. There is no `.exe` to download, run as administrator, or keep in a startup folder. * **Works with hosted QuickBooks** (e.g. Rightworks), where the Web Connector is already installed. * **Supports V2 flows.** * **Tables are selected via field map**, like a normal cloud connector. Because QBWC polls hotglue on an interval rather than holding an open connection, reads and writes are asynchronous: a job queues its requests and completes once the Web Connector's next sync processes them. ## Enable and set up your connector in hotglue ### Set up your flows Enable the QuickBooks Web Connector in your read flow, and in your write flow if you need to write data back to QuickBooks Desktop. The data format for both reads and writes is the same as the installed QuickBooks Desktop connector. For detailed behavior and business logic (upserts, processing order, batching, and per-record errors), see the [connector README](https://github.com/hotgluexyz/target-qbwc). ### What your tenant needs Each tenant needs two things to connect the Web Connector: | Item | Description | | :- | :- | | Platform | [QuickBooks Desktop Web Connector](https://api) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-qbwc](https://github.com/hotgluexyz/tap-qbwc) | | Target Repo | [https://github.com/hotgluexyz/target-qbwc](https://github.com/hotgluexyz/target-qbwc) | | Tap Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Target Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Connector password | A string that authenticates the Web Connector to push and pull data for the connected tenant. This is the same password used by the installed connector. | | `.qwc` file | The configuration file that tells the Web Connector how to communicate with hotglue. It embeds the tenant ID, so each tenant needs their own. | > [!WARNING] > > The `.qwc` file and connector password must belong to the same tenant ID. A file paired with another tenant's password will not work. ### Set up your tenant #### Option 1: Use the widget (recommended) The simplest way to set up a tenant is to link the QuickBooks Web Connector through the hotglue widget, either embedded in your app or opened via a magic link. Linking from the widget handles everything for you: * Generates the tenant's connector password * Links the tenant to your flows * Generates the tenant's `.qwc` file Once linked, the widget shows a download link for the `.qwc` file and a copy button for the connector password. The tenant can then follow the [end-user instructions](#end-user-instructions) below. **White-labeling:** The `.qwc` file sets the application name your tenants see in QuickBooks and the Web Connector. To use your own branding for `.qwc` files downloaded from the widget, go to `Settings` > `Connectors` > `Quickbooks Web Connector` and change these values: ```json theme={null} "qbwc_app_id": "hotglue-web-connector", "qbwc_app_display_name": "Hotglue Web Connector" ``` #### Option 2: Set up the tenant via API If you'd rather set up tenants programmatically, you can generate the password, link the tenant, and generate the `.qwc` file yourself. **1. Generate the connector password** The Web Connector accepts the same connector password as the installed connector, and uses the same endpoint to generate it: ```bash cURL theme={null} theme={null} curl 'https://api.hotglue.com////taps/quickbooks-desktop/token?write_flow_id=' \ --header 'x-api-key: ' ``` > [!TIP] > > If you haven't generated a signing key before, this request will error with: > **No signing key has been created for this environment.** To resolve, go to `Settings` > `API Keys`, and click `Generate Signing Key`. **2. Link the source** Pass the connector password as `token` in the config of a [POST to /linkedSources](/api-reference/v1/linked-sources/link-a-source). Unlike the installed connector, you don't pass `company_file_path` or `tables`; tables are selected via field map. ```bash cURL theme={null} theme={null} curl 'https://api.hotglue.com////linkedSources' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "source": { "tap": "qbwc", "config": { "token": "" } } }' ``` **source** `object` *required* **tap** `string` *required* `qbwc` **config** `object` *required* **token** `string` *required* The connector password generated in the previous step. **3. Link the target (write flows only)** If you're writing data to QuickBooks Desktop via a separate V1 write flow, either symlink the target config to the source config, or pass the same `token` in a POST to `/linkedTargets`: ```bash cURL theme={null} theme={null} curl 'https://api.hotglue.com////linkedTargets' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "target": { "target": "qbwc", "config": { "token": "" } } }' ``` **4. Generate the .qwc file** Generate the tenant's `.qwc` file from the following public URL: ``` https://qbwc.hotglue.com/qwc?tenant_id=&app_id=hotglue-web-connector&app_display_name=Hotglue+Web+Connector ``` | Parameter | Description | | :- | :- | | `tenant_id` | The tenant ID. Must match the tenant the connector password was generated for. | | `app_id` | Identifier for the application in the Web Connector. Replace to white-label. | | `app_display_name` | Name shown to the user in QuickBooks and the Web Connector (URL-encoded). Replace to white-label. | > [!NOTE] > > The `.qwc` file isn't secret on its own, since it only works alongside the matching connector password. You must still generate a separate file for each tenant, because it embeds the tenant ID. Once you have the connector password and `.qwc` file, send both to your tenant along with the [end-user instructions](#end-user-instructions) below. ### Optional: Connect additional company files Each QuickBooks company file is connected as its own [subtenant](/key-concepts/tenants/subtenants). For each additional company file: 1. Create a subtenant in hotglue (for example, `test-user_1`). 2. Get a connector password and `.qwc` file for the subtenant, either by linking the Web Connector in the widget for the subtenant, or by following the API steps above with the subtenant ID in place of ``. 3. Have the user open the other company file and repeat the [end-user instructions](#end-user-instructions) with the subtenant's `.qwc` file and password. ## End-user instructions ### Requirements **1. QuickBooks Desktop with the QuickBooks Web Connector** Only Windows versions are supported. The Web Connector comes pre-installed with modern versions of QuickBooks Desktop, and is already installed on hosted QuickBooks environments such as Rightworks. **2. The `.qwc` configuration file** **3. The connector password** ### Connect the Web Connector > [!WARNING] > > If you previously used the hotglue QuickBooks Desktop Connector (`.exe`) on this machine, stop it and remove it from your startup folder before continuing. **1. Open your company file** Open QuickBooks Desktop and log in to the company file you want to connect. **2. Open the Web Connector** Go to `File` > `App Management` > `Update Web Services`. **3. Add the application** Click `Add an Application` and select the downloaded `.qwc` file. When QuickBooks asks you to authorize the new web service, click `OK`. **4. Grant access** QuickBooks will ask what access to give the application. Select **Yes, always; allow access even if QuickBooks is not running**, and choose a QuickBooks user that won't cause access conflicts (for example, a user that isn't also logged in to the company file by someone else). Then click `Continue` and `Done`. > [!NOTE] > > If you've used the installed hotglue connector, this is the same access prompt you saw then. **5. Enter the password and enable syncing** You'll return to the Web Connector's list of applications, which now includes the hotglue application. For that application: 1. Enter the connector password in the `Password` field (click `Yes` if asked to save it). 2. Check `Auto-Run`, and set `Every Min` to `5`. 3. Check the checkbox on the left of the application's row, and click `Update Selected`. Once the update completes successfully, the Web Connector will sync with hotglue every 5 minutes and you're ready to start running jobs. ## Migrating from the installed connector To move an existing tenant from the installed QuickBooks Desktop connector: 1. Enable the QuickBooks Web Connector in your read and write flows. Your existing export script continues to work as-is. 2. Get the tenant's connector password and `.qwc` file, either by linking the Web Connector in the widget or via the API (see [Set up your tenant](#set-up-your-tenant)). 3. Select tables via field map. 4. Have the tenant stop the installed connector, remove it from their startup folder, and follow the [end-user instructions](#end-user-instructions). # QLS Source: https://docs.hotglue.com/connectors/qls # Connector Details | Name | Value | | :- | :- | | Platform | [QLS](https://qls.nl) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-qls](https://gitlab.com/hotglue/tap-qls) | | Target Repo | [https://gitlab.com/hotglue/target-qls](https://gitlab.com/hotglue/target-qls) | | Tap Metrics | Usage: (high) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Qomon Source: https://docs.hotglue.com/connectors/qomon # Connector Details | Name | Value | | :- | :- | | Platform | [Qomon](https://qomon.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-qomon](https://github.com/hotgluexyz/tap-qomon) | | Target Repo | [https://github.com/hotgluexyz/target-qomon](https://github.com/hotgluexyz/target-qomon) | | Target Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| # Azure Queue Storage Source: https://docs.hotglue.com/connectors/queue-storage # Connector Details | Name | Value | | :- | :- | | Platform | [Azure Queue Storage](https://learn.microsoft.com/en-us/azure/storage/queues/storage-queues-introduction) | | Auth Type | API Keys | | Direction | Write | | Target Repo | [https://github.com/hotgluexyz/target-queue-storage](https://github.com/hotgluexyz/target-queue-storage) | | Target Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup **Step 1** #### Step 1: Find your Storage Account First, you will need to go to the [Azure Portal](https://azure.microsoft.com/en-us/get-started/azure-portal). Sign in to your Azure Portal. Use the search bar and search for `storage account`. Click on `Storage accounts`. ![](https://mintcdn.com/hotglue/XqnG6T0_dJGIRgHM/connectors/images/QueuestorageSearchAccount.png?fit=max\&auto=format\&n=XqnG6T0_dJGIRgHM\&q=85\&s=bc1fb9250cd8ef522bf0a6f2e0336ad8) Find the storage account that contains the Queue you want to connect to. Click on its name. ![](https://mintcdn.com/hotglue/XqnG6T0_dJGIRgHM/connectors/images/QueuestorageSelectStorageAccount.png?fit=max\&auto=format\&n=XqnG6T0_dJGIRgHM\&q=85\&s=baf40f6af543f4f9a2e71c73ffac8585) **Step 2** #### Step 2: Create a Shared Access Signature and Connection String Once you click on the name of the storage account, you will see a pop up with a sidebar. In the sidebar, go to `Security + networking` and click on `Shared access signature`. You must select the following options: * `Allowed services` : `Queue` * `Allowed resource types` : `Container`, `Object` * `Allowed permissions` : `Read`, `Write`, `Delete`, `List`, `Add`, `Create`, `Update`, `Process` ![](https://mintlify.s3.us-west-1.amazonaws.com/hotglue/connectors/images/QueueStorageDetails.png) For the `Start and expiry date/time` section, you should set the fields as follows: * `Start`: Do not touch the start time, it should be the current datetime. * `End`: This is when Hotglue's access to your queue storage will stop. You will have to get new credentials (repeat this entire process) each time you hit this end date. For the `Allowed IP addresses`, leave the section blank. If your organization requires otherwise, you should contact us directly. > [!WARNING] > > You must read the following about `Signing keys`, as it may affect how long the connection string credentials will be valid. Choose your `Signing key` with the following considerations: * Every time your `Signing key` (`Access key`) is rotated/regenerated, you will have to get new credentials (repeat this entire process) again. * If you need more information, we recommend looking at [Microsoft's Docs](https://learn.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage?tabs=azure-portal) Click on `Generate SAS and connection string`. ![](https://mintcdn.com/hotglue/XqnG6T0_dJGIRgHM/connectors/images/QueuestorageScrolledDownDetails.png?fit=max\&auto=format\&n=XqnG6T0_dJGIRgHM\&q=85\&s=db51218f632897630a5b3cce5d23a72a) **Step 3** #### Step 3: Copy Credentials to Hotglue For this step, you will need to copy over the `Connection string` to Hotglue. ![](https://mintcdn.com/hotglue/XqnG6T0_dJGIRgHM/connectors/images/QueuestorageCopyCredentials.png?fit=max\&auto=format\&n=XqnG6T0_dJGIRgHM\&q=85\&s=5a18e901e62bad45b5b615ccc685c8f8) Your `Queue Name` is the name of your queue in Azure. Your `Queue Key` is a label of your choice. Save your credentials. Congratulations! You have successfully connected your Queue Storage to Hotglue! # QuickBooks Source: https://docs.hotglue.com/connectors/quickbooks # Connector Details | Name | Value | | :- | :- | | Platform | [QuickBooks](https://quickbooks.intuit.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-quickbooks](https://github.com/hotgluexyz/tap-quickbooks) | | Target Repo | [https://github.com/hotgluexyz/target-quickbooks-v2](https://github.com/hotgluexyz/target-quickbooks-v2) | | Tap Metrics | Usage: (high) | | Target Metrics | Usage: (low) | | Unified Schema | Supported in [Accounting Unified Schema](https://hotglue.com/docs/unified). (Supported tables: Accounts, Bills, Customers, Items, Vendors, Invoices, GeneralLedgerReport, ProfitAndLossReport, Classes, CustomerTypes, PaymentMethods, PaymentTerms, Departments, TaxRates) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Credentials Setup Follow the steps below to get the credentials you need to use the QuickBooks connector. To create a QuickBooks OAuth app, you will need to register for a [free developer account](https://developer.intuit.com/app/developer/qbdesktop/docs/get-started/create-an-intuit-developer-account) on the [Intuit Developer Portal](https://developer.intuit.com/app/developer/homepage). Once you have registered for an Intuit Developer account, you should be able to access the [Developer Dashboard](https://developer.intuit.com/app/developer/dashboard) which should look something like below: ![](https://files.readme.io/0a96285-developer.intuit.com_app_developer_dashboard.png) From here, you can create an OAuth app by selecting Create an app. Select QuickBooks Online and Payments as the platform you want to develop for, as pictured below: ![](https://files.readme.io/ca84494-developer.intuit.com_app_developer_dashboard_1.png) You will then need to provide an app name, scope, and select the teamt o access the app. hotglue integrations generally **do not** deal with QuickBooks Payments, so you can just select the `com.intuit.quickbooks.accounting` scope as pictured below: ![](https://files.readme.io/d139931-developer.intuit.com_app_developer_dashboard_2.png) Once done, select **Create app**. This will take you to the App settings page, where you can configure two separate sets of credentials: * **Development Settings** gives you credentials / settings for configuring an OAuth app to access QuickBooks Online Sandbox accounts. This is only for testing purposes. * **Production Settings** gives you credentials / settngs for configuring an OAuth app to access QuickBooks Online Production accounts. For this example, I will walk through the **Development Settings**, as the process is the same for both. Click on **Keys & credentials** ![](https://files.readme.io/b1718b9-developer.intuit.com_app_developer_dashboard_3.png) You should then see a screen similar to below, where you can a **Redirect URI**: ![](https://files.readme.io/dcc66eb-developer.intuit.com_app_developer_dashboard_4.png) From this screen, add ` as a valid redirect URI. If you do not do this step, hotglue will not be able to make OAuth connections on your behalf. Once done, click **Save** ![](https://files.readme.io/bc800d6-Screen_Shot_2022-08-23_at_4.55.18_PM.png) Now you can insert the client id and client secret pair from the **Keys** section into your hotglue QuickBooks source settings. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.6.4](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.6.4) | | > | [v1.6.3](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.6.3) | | > | [v1.6.2](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.6.2) | | > | [v1.6.1](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.6.1) | | > | [v1.6.0](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.6.0) | | > | [v1.5.17](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.17) | | > | [v1.5.16](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.16) | fixes | > | [v1.5.15](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.15) | fixes | > | [v1.5.14](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.14) | bug fixes | > | [v1.5.13](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.13) | bug fixes | > | [v1.5.12](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.12) | fixes | > | [v1.5.11](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.11) | | > | [v1.5.10](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.10) | | > | [v1.5.9](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.9) | | > | [v1.5.8](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.8) | | > | [v1.5.7](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.7) | | > | [v1.5.6](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.6) | | > | [v1.5.5](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.5) | | > | [v1.5.4](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.4) | | > | [v1.5.3](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.3) | | > | [v1.5.2](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.2) | | > | [v1.5.1](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.1) | | > | [v1.5.0](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.5.0) | | > | [v1.4.53](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.53) | | > | [v1.4.52](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.52) | | > | [v1.4.49](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.49) | | > | [v1.4.48](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.48) | | > | [v1.4.47](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.47) | | > | [v1.4.46](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.46) | | > | [v1.4.45](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.45) | | > | [v1.4.44](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.44) | | > | [v1.4.43](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.43) | | > | [v1.4.42](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.42) | | > | [v1.4.41](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.41) | | > | [v1.4.39](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.39) | | > | [v1.4.38](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.38) | | > | [v1.4.37 - Include description on invoice and credit line item](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.37) | Include description on invoice and credit line item | > | [v1.4.36 - Add Support for SalesReceipt](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.36) | Adds support for `SalesReceipt` entity | > | [v1.4.35 - P\&L Stream Fixes](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.35) | Fixed bug with P\&L stream when malformed data was passed in | > | [v1.4.34](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.34) | Hot fix on `v1.4.33` for normal streams | > | [v1.4.33](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.33) | Enable full sync of P\&L report when state is not passed | > | [v1.4.32 - P\&L Report fixes](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.32) | - Avoid returning if current period has no data in P\&L | > | [v1.4.31 - Add support for Qty and UnitPrice in invoice line](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.31) | Add support for Qty and UnitPrice in invoice line | > | [v1.4.30 - Support for Purchases and TimeActivity](https://github.com/hotgluexyz/tap-quickbooks/releases/tag/v1.4.30) | Added two more QBO entities to discoverable list. | # QuickBooks Desktop Source: https://docs.hotglue.com/connectors/quickbooks-desktop # Connector Details | Name | Value | | :- | :- | | Platform | [QuickBooks Desktop](https://api) | | Auth Type | On-Premise | | Direction | Bidirectional | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (low) | | Unified Schema | Supported in [Accounting Unified Schema](https://hotglue.com/docs/unified). (Supported tables: Bills, Accounts, Vendors, Projects) | # Overview Quickbooks Desktop is on-premise accounting software. It is a distinct product from Quickbooks Online. The hotglue Quickbooks Desktop connector is an installed program (.exe) that is run on the same machine that manages the Quickbooks company file. While running, the connector allows you to read and write data like you would with a normal cloud connector. ## Enable and set up your connector in hotglue ### Set up your flow To utilize the Quickbooks Desktop connector, you first need to add Quickbooks Desktop to a flow. You only need to do this once. 1. Click `Add Flow` on the left-side toolbar. 2. Give your flow a name and description, and choose `Source Flow`. 3. After creating your flow, go to the `Sources` tab and click on Quickbooks Desktop. If you would like to write data back to QBD, you will also need to generate a target flow. If you only need to pull data out of QBD, you can skip this step: 1. Click `Add Flow` on the left-side toolbar. 2. Give your flow a name and description, and choose `Target Flow`. 3. After creating your flow, go to the `Targets` tab and click on Quickbooks Desktop. ### Set up your tenant Unlike cloud connectors, which offload authentication to the user, Quickbooks Desktop authentication requires you to make two API requests per tenant. **1. Link the tenant** The first request is a [POST to /linkedSources](/api-reference/v1/linked-sources/link-a-source) with a config object. This request "links" the tenant to your read flow, and creates the tenant if it doesn't already exist. ```bash cURL theme={null} curl 'https://api.hotglue.com////linkedSources' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "source": { "tap": "quickbooks-desktop", "config": { "company_file_name": "C:\\Users\\Public\\Documents\\Intuit\\QuickBooks\\Company Files\\hotglue.QBW", "tables": { "account": { "sync": true, "replication_key": "TimeModified" }, "bill": { "sync": true, "replication_key": "TimeModified" } } } } }' ``` **source** `object` *required* **tap** `string` *required* `quickbooks-desktop` **config** `object` *required* **company\_file\_name** `string` *required* The full path to the Quickbooks Desktop Company file **tables** `array` *required* Defines which tables to sync and their properties. the keys (e.g., `account`, `bill`) are table names that can be customized dynamically. **properties** **\** `string` *required* Each table can have the following fields **sync** `boolean` *required* Set to `true` to sync the table. **replication\_key** `string` Set to the datetime field you would like to incrementally fetch records based on. Usually `TimeModified` if present. **2. Generate the connector password** The next request will return the "connector password" for your configured user. Your tenant will use the connector password to authenticate their connector on their machine. ``` curl 'https://api.hotglue.com////taps/quickbooks-desktop/token?write_flow_id=' \ --header 'x-api-key: ' ``` > [!TIP] > > If you haven't generated a signing key before, this request will error with: > **No signing key has been created for this environment.** To resolve, go to `Settings` > `API Keys`, and click `Generate Signing Key`. Once your connector password is generated, you are ready to run the connector and start running jobs! **3. Optional: Enable additional Quickbooks company files** After you generate a config and password for one company, you can add additional company files for the connector to sync. This is done by utilizing [subtenants](https://docs.hotglue.com/key-concepts/tenants/subtenants). Every time the connector runs on its cycle (usually every 60 seconds), it checks if the connected tenant has subtenants. If subtenants exist, it iterates through processing for each subtenant. Once enabled in Settings > Widget, you can create subtenants via the syntax: ``` root_tenant_id + {subtenant delimeter} + {any string} ``` The default subtenant delimeter in all hotglue environments is `_`. That means if your initial `POST /linkedSources` looks like: ``` /dev.hg.test.com/AAAAAA/test-user/linkedSources ``` then the URL of a subtenant creation request should look like: ``` /dev.hg.test.com/AAAAAA/test-user_1/linkedSources ``` > [!TIP] > > **NOTE:** Do not generate connector passwords for subtenants. Subtenants are created via new linkedSource entries (Step 1) ONLY. ## End-user instructions ### Requirements **1. The Quickbooks Desktop Connector and Password** **2. QuickBooks Desktop application** Only Windows versions are supported. You can obtain a 30-day free trial via [Intuit's website](https://quickbooks.intuit.com/desktop/enterprise/contact/trial-download/). **3. QuickBooks SDK** This must be downloaded on the same machine as the connector. You can install the latest from [Intuit's Website](https://developer.intuit.com/app/developer/qbdesktop/docs/get-started/download-and-install-the-sdk). ### Run the connector > [!NOTE] > > The Quickbooks Desktop connector is packaged as a .exe file. It is signed with an Extended Validation Code Signing Certificate issued by Sectigo, meaning it is verified and cannot be tampered with. > [!WARNING] > > Make sure Quickbooks Desktop is open and you are logged in to the Company File as an Administrator User before running the Quickbooks Desktop Connector **1. Download the connector launcher file.** **2. (Optional) Move the connector launcher to your startup folder** This ensures that the connector runs automatically when you restart your machine. To configure this: 1. Right click the windows icon on the bottom left 2. Select `run`, then type `shell:startup` > OK 3. This will open your startup folder. Drag the launcher from your downloads folder to here. **3. Run the connector launcher** Right-click > `Run as administrator` **4. Enter the connector password** After the connector boots up, you will see a dialog requesting the connector password. Enter the password. If the pop-up closes, that means the password is accepted, the connector is installed, and you are ready to begin syncing data. # Connector Capabilities The QuickBooks Desktop connector supports both read and write. Learn more below. ## Read To read data from QuickBooks Desktop, you simply configure the `tables` section in the config. A list of supported objects for read is provided below. ### Supported Objects * account * balance\_sheet\_detail * balance\_sheet\_summary * bill * check * class * credit\_memo * customer * estimates * invoice * item * item\_sales\_tax * journal\_entry * price\_level * profit\_and\_loss * profit\_and\_loss\_budget * purchase\_order * sale\_order * sales\_receipt * sales\_tax\_code * transaction\_list * unit\_of\_measure\_set * vendor ## Write The QuickBooks Desktop connector also supports writing objects, using JSON files that follow the [qbXML raw schema](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop). > [!NOTE] > > When writing data to QuickBooks Desktop, ensure that the `.json` files are written to the `etl-output` folder in your jobs. Otherwise the connector will not process them. ### File Formatting Currently the connector supports only `JSON` files, and must follow the following criteria: * Files must be named following the convention `(-).json`, where: * `` is the lowercase name of the connector object (e.g., `customer`, `invoice`) * `-` is optional and can be any descriptive string (e.g., `-may`, `-20250715`) | **✅ Valid File Names** | **❌ Invalid File Names** | | - | - | | `customer.json` | `Customer.json` | | `customer-may.json` | `CustomerAddRq.json` | | `customer-20250715.json` | | * All keys in the JSON file must appear in **exactly** the same order as shown in the official qbXML documentation. For example: ```json invoice-valid.json ✅ theme={null} [ { "CustomerRef": { "FullName": "EAST NEW YORK HARDWARE" }, "RefNumber": "00026420", "InvoiceLineAdd": [ { "ItemRef": { "FullName": "NFR-SH86150" }, "Quantity": "1", "Amount": "100.00" } ] } ] ``` ```json invoice-invalid.json ❌ theme={null} [ { "InvoiceLineAdd": [ { "ItemRef": { "FullName": "NFR-SH86150" }, "Quantity": "1", "Amount": "100.00" } ], "CustomerRef": { "FullName": "EAST NEW YORK HARDWARE" }, "RefNumber": "00026420" } ] ``` ### Supported Objects Below is a list of Hotglue QBD connector object names, and the corresponding qbXML requests that they use. | Connector Object Name | qbXML Request | | - | - | | `customer` | [CustomerAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/customeradd) | | `invoice` | [InvoiceAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/invoiceadd) | | `bill` | [BillAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/billadd) | | `sales_order` | [SalesOrderAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/salesorderadd) | | `credit_memo` | [CreditMemoAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/creditmemoadd) | | `vendor` | [VendorAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/vendoradd) | | `vendor_credit` | [VendorCreditAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/vendorcreditadd) | | `item_inventory` | [ItemInventoryAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/iteminventoryadd) | | `item_noninventory` | [ItemNonInventoryAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/itemnoninventoryadd) | | `sales_receipt` | [SalesReceiptAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/salesreceiptadd) | | `journal_entry` | [JournalEntryAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/journalentryadd) | | `item_sales_tax` | [ItemSalesTaxAddRq](https://developer.intuit.com/app/developer/qbdesktop/docs/api-reference/qbdesktop/itemsalestaxadd) | # Quickbutik Source: https://docs.hotglue.com/connectors/quickbutik # Connector Details | Name | Value | | :- | :- | | Platform | [Quickbutik](https://quickbutik.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-quickbutik](https://gitlab.com/hotglue/tap-quickbutik) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # ReCharge Source: https://docs.hotglue.com/connectors/recharge # Connector Details | Name | Value | | :- | :- | | Platform | [ReCharge](https://rechargepayments.com) | | Auth Type | API Keys | | Direction | Read | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Recurly Source: https://docs.hotglue.com/connectors/recurly # Connector Details | Name | Value | | :- | :- | | Platform | [Recurly](https://recurly.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-recurly](https://gitlab.com/hotglue/tap-recurly) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Reddit Source: https://docs.hotglue.com/connectors/reddit # Connector Details | Name | Value | | :- | :- | | Platform | [Reddit](https://reddit.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-reddit](https://gitlab.com/hotglue/tap-reddit) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the Reddit connector. The first thing you need to do is log in to the [Reddit](https://www.reddit.com/login/). ![](https://files.readme.io/82e1163-reddit-011.png "reddit-011.png") Enter the credentials and click on **Sign in** button. ![](https://files.readme.io/2896177-reddit-02.png "reddit-02.png") Navigate to "[Reddit Apps](https://www.reddit.com/prefs/apps)". Create a new app. ![](https://files.readme.io/310c303-reddit-04.png "reddit-04.png") Enter the credentials. You should add the Redirect URI `https://hotglue.xyz/callback`. ![](https://files.readme.io/8134e18-reddit-05.png "reddit-05.png") Once you are done, you can also get your Client ID and Client Secret. Now you can go ahead and copy the credentials into hotglue. # AWS Redshift Source: https://docs.hotglue.com/connectors/redshift # Connector Details | Name | Value | | :- | :- | | Platform | [AWS Redshift](https://aws.amazon.com/redshift) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-redshift](https://github.com/hotgluexyz/tap-redshift) | | Target Repo | [https://github.com/hotgluexyz/target-redshift](https://github.com/hotgluexyz/target-redshift) | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (high) | # Credentials Setup The AWS Redshift connector uses the following 12 connection parameters: ```json theme={null} { "Host": "example-cluster.xxx123.us-xxx-1.redshift.amazonaws.com", "Port": "xxxx", "User": "xxx_user", "Password": "xxxxxx", "Database Name": "database_name", "Access Key Id": "xxxxx", "Secret Access Key": "xxxxxx", "S3 Bucket": "my-redshift-staging-bucket", "Default Target Schema": "xxx", "SSH Host": "12.345.67.89", "SSH User": "xxx-user", "SSH Key": "xxxx.pem" } ``` Follow the steps below to find each of these in AWS. ### 1. `Host` This is the Redshift endpoint hostname. **Where to get it:** 1. Sign in to the AWS Console. 2. Open Amazon Redshift. ![Go to AWS Redshift](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20Redshift.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=763acac3c055075df0f3face81de733c) 3. Go to Clusters and select your Redshift cluster. ![Go to Clusters & select your redshift cluster](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20Redshift%20cluster.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=d24bf48fead0b5ce19ad3cae8694cff5) 4. In the cluster details, find the Endpoint. ![Locate Endpoint - Host](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20Redshift%20Endpoint%20-%20Host.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=7a3470757f223b3b65390671abe169a0) **What to enter**: Copy the hostname from the Endpoint (the part before the colon `:`), for example: ``` example-cluster.abc123.us-east-1.redshift.amazonaws.com ``` ### 2. `Port` The port Redshift listens on. **Where to get it:** Follow steps 1, 2, 3 and 4 for getting **Host** credentials. Then follow these steps: 5. In the cluster details, find the Endpoint. ![Locate Endpoint - Port](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20Redshift%20Endpoint%20-%20Port.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=6e6833e08508a3007d01d50754afec52) Copy the port from the Endpoint (the part after the colon `:` and before the slash `/`). ### 3. `User` The Redshift user is created inside the Redshift database. **Where to get it:** Follow steps 1, 2 and 3 for getting **Host** credentials. Then follow these steps: 4. Click the Properties tab. ![Navigate to the Properties tab](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20Redshift%20Properties%20tab.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=21a80b824062e1f55aaf051109d695f7) 5. Scroll down to **Database configurations**. 6. Locate Admin user name. ![Locate Admin User Name](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20Redshift%20Admin%20User%20Name.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=f8a9b7b5129c7c5787448b6643140230) > [!NOTE] > > If you need a non-admin or dedicated user instead, contact your AWS administrator. We can also run the following query in Query Editor v2: ``` SELECT usename FROM pg_user; ``` If you need to create a dedicated user for integrations, run: ``` CREATE USER sample_user PASSWORD 'StrongPassword123'; ``` Use the created username as the User value when configuring the Redshift connector. ### 4. `Password` The password is set when the Redshift user is created; it is **not** visible in the AWS console afterward, so save it then. The password can be retrieved from **AWS Secrets Manager** if it was stored there at the time of cluster creation. ![Go to Secrets Manager](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20Redshift%20Secrets%20Manager.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=171fd2938a86e1e4e70f73f29993f2a6) **Where to set or reset the password**: Follow steps 1, 2 and 3 for getting **Host** credentials. Then follow these steps: 4. Click on Query Data. ![Navigate to Query data](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20Redshift%20Query%20data.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=0e39ffbbcd92737b230b5ad0b59f4889) 5. Open Query Editor v2. 6. Connect to your Redshift cluster or workgroup. If creating a new user: ``` CREATE USER sample_user PASSWORD 'StrongPassword123'; ``` If resetting the password for an existing user: ``` ALTER USER sample_user PASSWORD 'NewStrongPassword123'; ``` Use the password specified in the SQL command as the Password value when configuring the Redshift connector. ### 5. `Database Name` The database on your Redshift cluster—often `dev`, `analytics`, or another name your team uses. **Where to get it:** Follow steps 1, 2 and 3 for getting **Host** credentials. Then follow these steps: 4. Click the Properties tab. ![Navigate to the Properties tab](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20Redshift%20Properties%20tab.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=21a80b824062e1f55aaf051109d695f7) 5. Scroll down to Database configurations. 6. Locate Database name. ![Locate Database name](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20Redshift%20Database%20name.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=e81c650974335d4e1976f1e5c23537d3) ### 6. `Access Key Id` The AWS access key used for S3 access. **Where to get it:** 1. Open the AWS Console. 2. Go to IAM. ![Go to IAM](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/IAM.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=e19b03e36f649cfb257bca9849f89084) 3. Select Users. ![Click on Users](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/IAM%20Users.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=f985e8465892807f7a5d1b734370836c) 4. From the list of Users, click the IAM user that will be used for the integration. 5. Open the Security credentials tab. ![Go to Security Credentials to get Access Key workflow](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/IAM%20Security%20Credentials.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=b4df4f8d7875a4be8479d43730d01aef) 6. Under Access keys, create or view the relevant access key metadata. ### 7. `Secret Access Key` The secret paired with the Access Key Id. > [!WARNING] > > AWS only shows the secret access key once at the time the access key is created. If it wasn’t saved, your admin must generate a new access key. Lost keys cannot be recovered. **Where to get it:** Create a new access key for the IAM user if needed, then copy the secret when it is shown and store it securely. ### 8. `S3 Bucket` The S3 bucket used for staging data. **Where to get it:** 1. Open the AWS Console. 2. Go to Amazon S3. ![Navigate to S3](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20S3.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=35b1f21ffd04f785041f191c28893f06) 3. Click on General purpose buckets. ![Click on General Purpose Buckets](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/AWS%20S3%20General%20Purpose%20Buckets.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=57a5ff028e8f756df9d1049a73070166) 4. From the list of buckets, copy the name of the bucket your team uses for Redshift staging. ### 9. `Default Target Schema` Schema name for data loaded into Redshift. > [!NOTE] > > Schemas are **not** visible in the AWS Console without SQL access. You will need to use a SQL client (e.g., DBeaver, TablePlus, or psql) connected to your Redshift cluster. **Where to get it:** 1. Open your **SQL client** and connect to your Redshift cluster using your Host, Port, Database, User, and Password credentials. 2. Once connected, run the following query: ``` SELECT schema_name FROM information_schema.schemata; ``` 3. Pick the schema where data should land and enter it as Default Target Schema. If unsure, common choices are `public`, `analytics`, or `raw`. If none exists yet, ask your administrator to create one; `public` is a safe default. ### 10. `SSH Host` The public IP address of the EC2 bastion host used to establish the SSH tunnel to the Redshift cluster. > [!NOTE] > > SSH fields are only required if your Redshift cluster is not publicly accessible and requires an SSH tunnel. If your cluster is publicly accessible, you can leave these fields empty. **Where to get it:** 1. Go to AWS Console 2. Open EC2 ![Click on EC2](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/EC2.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=c6e97e0ea44fda83cad3bc6390e12d24) 3. Click Instances ![Go to Instances](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/EC2%20Instances.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=85e2025acde662ad7abbdecae65abbb5) 4. Select the bastion host instance 5. Locate Public IPv4 address ![Locate Public IPv4 address](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/EC2%20Public%20IPv4%20address.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=a29c3e841902e6c58f66daab2fc10c8c) Use this value as the SSH Host. ### 11. `SSH User` The username depends on the AMI; see [AMI default user names](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/managing-users.html#ami-default-user-names) in the AWS docs. **Where to verify:** Follow steps 1, 2, 3 and 4 for getting **SSH Host** credentials. Then follow these steps: 5. In the **Details** tab, check Platform details/AMI ![Locate Platform Details/AMI](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/EC2%20Platform%20Details.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=fbe58d81b5b07a34f7d6da7d53ce45d0) If the instance is running Amazon Linux, the SSH user is ec2-user. ### 12. `SSH Key` The private key file (.pem) associated with the EC2 key pair used when the bastion host instance was launched. **Where to find the key pair name:** Follow steps 1, 2, 3 and 4 for getting **SSH Host** credentials. Then follow these steps: 5. In the **Details** tab, locate Key pair assigned at launch ![Locate Key pair assigned at launch](https://mintcdn.com/hotglue/O2e0ZuAUkBURj1g-/connectors/images/EC2%20Key%20pair.png?fit=max\&auto=format\&n=O2e0ZuAUkBURj1g-\&q=85\&s=2a4294a6e9f75463c32025c869e63ac8) The name under Key pair assigned at launch matches your `.pem` file (for example, `my-bastion-key` → `my-bastion-key.pem`). That file was downloaded when the key pair was created and cannot be retrieved from AWS again. You can also view the key pair in: ``` EC2 → Network & Security → Key Pairs ``` > [!WARNING] > > If the key is lost, a new key pair must be created and associated with the instance. # Target Changelog > [accordion] Target Changelog > > | Version | Notes | > | :- | :- | > | [v1.6.3](https://github.com/hotgluexyz/target-redshift/releases/tag/v1.6.3) | | # Restaurant365 Source: https://docs.hotglue.com/connectors/restaurant365 # Connector Details | Name | Value | | :- | :- | | Platform | [Restaurant365](https://restaurant365.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-restaurant365](https://github.com/hotgluexyz/tap-restaurant365) | | Target Repo | [https://gitlab.com/hotglue/target-restaurant365](https://gitlab.com/hotglue/target-restaurant365) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (low) | | Unified Schema | Supported in [Unified Schema](https://hotglue.com/docs/unified). (Supported tables: ProfitAndLossReport) | # Reviews.io Source: https://docs.hotglue.com/connectors/reviewsio # Connector Details | Name | Value | | :- | :- | | Platform | [Reviews.io](https://reviews.io) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-reviewsio](https://github.com/hotgluexyz/tap-reviewsio) | | Tap Metrics | Usage: (high) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Reviews.io connector. The first thing you need to do is log in to [Reviews.io](https://reviews.io). They have a free trial, so if you don't have an account, you can make one [here](https://www.reviews.io/front/pricingplans). If you already have an account, you can log in [here](https://dash.reviews.io/login). ![](https://files.readme.io/29d5e66-Screen_Shot_2021-11-26_at_11.45.23_AM.png "Screen Shot 2021-11-26 at 11.45.23 AM.png") Your home page should look something like this. On the left side of the screen, you should select the **Integrations** option in the navigation bar. ![](https://files.readme.io/338ff75-Screen_Shot_2021-11-26_at_11.52.20_AM.png "Screen Shot 2021-11-26 at 11.52.20 AM.png") You will now be on the integrations page. You should scroll down until you find the API integration card. ![](https://files.readme.io/0352140-Screen_Shot_2021-11-26_at_11.53.36_AM.png "Screen Shot 2021-11-26 at 11.53.36 AM.png") Now that you found it, go ahead and click the API card. ![](https://files.readme.io/a3bf5dc-Screen_Shot_2021-11-26_at_11.56.51_AM.png "Screen Shot 2021-11-26 at 11.56.51 AM.png") On this page, you now have both your Store ID and API Key! Go ahead and copy these into hotglue! # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.3](https://github.com/hotgluexyz/tap-reviewsio/releases/tag/v0.0.3) | | > | [v0.0.2](https://github.com/hotgluexyz/tap-reviewsio/releases/tag/v0.0.2) | - Fix invalid schema | # Rillet Source: https://docs.hotglue.com/connectors/rillet # Connector Details | Name | Value | | :- | :- | | Platform | [Rillet](https://www.rillet.com/) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-rillet](https://github.com/hotgluexyz/tap-rillet) | | Target Repo | [https://github.com/hotgluexyz/target-rillet](https://github.com/hotgluexyz/target-rillet) | | Tap Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Target Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Credentials Setup Follow the steps below to get the credentials you need to use the Rillet connector. | Field Name | Description | | :- | :- | | API Key | Your Rillet API Key | ## API Key 1. The first thing you need to do is log in to your [Rillet](https://www.rillet.com/) account. ![Login to Rillet account](https://mintcdn.com/hotglue/xYv85CKjbar_fbO4/connectors/images/Rillet%20Home%20Screen.png?fit=max\&auto=format\&n=xYv85CKjbar_fbO4\&q=85\&s=b73134619e86a0733cfe51dac3b67625) 2. On the bottom left corner of the screen, click on **Organization Settings**. ![Organization Settings](https://mintcdn.com/hotglue/xYv85CKjbar_fbO4/connectors/images/Rillet%20Go%20to%20Organization%20Settings.png?fit=max\&auto=format\&n=xYv85CKjbar_fbO4\&q=85\&s=2b3b4be69dcc6f82c065788b7d833222) 3. Under the organization section on the left sidebar, select **API Access**. ![Click on API Access](https://mintcdn.com/hotglue/xYv85CKjbar_fbO4/connectors/images/Rillet%20Go%20to%20API%20Access.png?fit=max\&auto=format\&n=xYv85CKjbar_fbO4\&q=85\&s=8e9f5fc529c26f4ba910092990d4763b) 4. On the top right corner, click on the **+ Create API Key** icon. ![Click on API Access](https://mintcdn.com/hotglue/xYv85CKjbar_fbO4/connectors/images/Rillet%20Click%20on%20Create%20API%20Key.png?fit=max\&auto=format\&n=xYv85CKjbar_fbO4\&q=85\&s=1cfddcc8143b6fb4ecda6b87a1225c74) 5. Enter an **API Key Name** and click **+ Create API Key** to generate your key. ![Generate API Key](https://mintcdn.com/hotglue/xYv85CKjbar_fbO4/connectors/images/Rillet%20Generate%20API%20Key.png?fit=max\&auto=format\&n=xYv85CKjbar_fbO4\&q=85\&s=f821ea5099718410f8866c3b928c1ce4) Once your API Key is generated, copy it and paste it into the hotglue connector setup. > [!WARNING] > > Make sure to copy your API Key immediately after generating it. You will not be able to view it again once you close this window. # Ringcentral Source: https://docs.hotglue.com/connectors/ringcentral # Connector Details | Name | Value | | :- | :- | | Platform | [Ringcentral](https://ringcentral.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/dbt-labs/tap-ringcentral](https://github.com/dbt-labs/tap-ringcentral) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # AWS S3 Source: https://docs.hotglue.com/connectors/s3 # Connector Details | Name | Value | | :- | :- | | Platform | [AWS S3](https://aws.amazon.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Metrics | Usage: (high) | | Target Metrics | Usage: (high) | # Overview You can use the S3 connector to read and write files with S3. # How to authenticate S3 ### Determining the appropriate IAM Policy However you choose to authenticate, you will need to determine an appropriate IAM policy for your integration. The policy you create depends on your integration needs: * Exporting to S3: Only needs `s3:PutObject` * Fetching from S3: Needs `s3:ListBucket` and `s3:GetObject` Here's a policy for both reading and writing. Replace `BUCKET_NAME` with your bucket: ``` { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::BUCKET_NAME/*", "arn:aws:s3:::BUCKET_NAME" ] } ] } ``` Once you have your policy, you have two ways to authenticate with S3: 1. HMAC Access Key ID and Secret (default) 2. Cross-account role with external ID ## Method 1: HMAC Access Key ID and Secret By default, the S3 connector authenticates using an Access Key ID and Secret Access Key. ### Step 1: Create an IAM User 1. In AWS, navigate to IAM service 2. Go to **Users** > **Create user** 3. Enter a user name 4. Select **Access key - Programmatic access** 5. Click **Next: Permissions** ### Step 2: Create and Attach Policy 1. Click **Attach policies directly** > **Create Policy** 2. Select the **JSON** tab and paste the policy from above. 3. Click **Next: Tags** > **Next: Review** 4. Name the policy and click **Create policy** 5. Return to the user creation workflow 6. Select your newly created policy 7. Click **Next: Review** > **Create user** 8. Copy your `Access Key ID` and `Secret Access Key`, and paste them into the widget. ⚠️ **Important**: This is your only chance to copy the Secret Access Key. Store it securely. ## Method 2: Cross-account AssumeRole with External ID For enterprises requiring temporary credentials and enhanced security controls, you can use cross-account role access. To enable this in hotglue, change the S3 `connect_ui_params` in your connector settings to include `aws_external_id` and `aws_role_arn` in lieu of `aws_access_key_id` and `aws_access_key_id`, like below: ```json theme={null} [ { "id":"s3", ... "connect_ui_params":{ "aws_external_id":{ "label":"AWS External Id", "description":"AWS External Id" }, "aws_role_arn":{ "label":"AWS Role ARN", "description":"Role ARN for IAM role" }, ... } } ] ``` Once `aws_external_id` is configured in your connector settings, the widget will automatically update to display a copy-pastable external ID for each tenant. Tenants will need this value to configure their settings in AWS. ![](https://mintcdn.com/hotglue/GfS44gfKEM21YGJn/connectors/images/hotglue_s3_external_id_auth.png?fit=max\&auto=format\&n=GfS44gfKEM21YGJn\&q=85\&s=ab1182d2f1863570a90af1722945dfd9) ### Step 1: Create IAM Policy 1. Navigate to IAM service 2. Go to **Policies** > **Create policy** 3. Select the **JSON** tab and paste the policy above. 4. Click **Next: Tags** > **Next: Review** 5. Name the policy and click **Create policy** ### Step 2: Create IAM Role 1. Navigate to **IAM** > **Roles** > **Create role** 2. Select **Custom trust policy** 3. Paste the trust policy below, replacing `EXTERNAL_ID` with the external ID copied from the widget: ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::581362835603:root" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "EXTERNAL_ID" } } } ] } ``` 1. Click **Next** 2. Select the policy created in Step 1 and click **Next** 3. Enter a Role name and click **Create role** 4. Copy the role's `ARN` from the summary page, and paste it into the widget. ## Configuring your bucket connection Each S3 connection accepts two key pieces of information: * `bucket`: Your S3 bucket name (e.g., `my-company-data`) * `path_prefix`: A specific path within your bucket (e.g., `incoming/orders`) The path prefix helps organize your data. For example, if you set: ``` path_prefix: exports/invoices ``` Files will be read from and written to that location in your bucket: ``` my-company-data/exports/invoices/ ``` ## Using variables in paths Make your paths dynamic by using variables in curly braces. For example: ``` orders/{tenant}/{date}/incoming ``` Could resolve to: ``` orders/acme-corp/202312/incoming ``` Available variables: | Variable | Description | Example Output | | - | - | - | | tenant | Your tenant ID | `acme_corp` | | root\_tenant\_id | Root tenant ID (for subtenants) | `acme` | | tap | Tap ID this job ran for | `salesforce` | | date | Current date (YYYYMM) | `202312` | | full\_date | Full date (YYYYMMDD) | `20231206` | | flow\_id | Flow identifier | `Fq183dc` | | job\_id | Internal job ID | `jklc4` | | external\_job\_id | External job ID | `order-123` | | env\_id | Environment | `prod.hg.acme.com` | ## Reading Files When reading from S3: * Files are copied from your bucket maintaining their directory structure * All files within your path\_prefix are processed, unless using incremental mode * File contents must be parsed in your transformation script ## Writing Files When writing to S3: * Files are written to your specified path\_prefix * Directory structure is created automatically if it doesn't exist * File naming and organization can also be controlled in your transformation script For example, setting: ``` bucket: customer-exports path_prefix: data/{tenant}/{date} ``` Might write files to: ``` customer-exports/ data/ acme-corp/ 202312/ orders.csv customers.csv ``` # Sage 300 CRE Source: https://docs.hotglue.com/connectors/sage-300-cre # Connector Details | Name | Value | | :- | :- | | Platform | Sage 300 CRE | | Auth Type | On-Premise | | Direction | Bidirectional | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (low) | # Overview Sage 300 CRE (Construction and Real Estate), formerly Timberline, is on-premise accounting software for construction and property management. It is a distinct product from [Sage 300](/connectors/sage300). The hotglue Sage 300 CRE connector is an installed Windows program (`.exe`) that runs on the same machine as Sage 300 CRE. While it is running, you can read and write data the same way you would with a cloud connector. * **Read** can sync any table exposed by the Sage 300 CRE ODBC database. Common objects also have friendly stream names (for example `vendor`, `job`, `bill`). * **Write** supports creating (and in some cases updating) vendors, jobs, cost codes, categories, journal entries, bills, and commitments. # Setup video guide [Connector setup guide](https://www.loom.com/embed/5623c6fdf5af48f4bb6296cf42686118) # Tenant setup guide Use the guide below to configure the Sage 300 CRE connector. ## Initial credential configuration Before installing the connector locally, gather the following: * **Username and password**: Sage 300 CRE credentials for the company. Empty values are valid for open or sample companies that do not require a login. For production companies, create a dedicated integration user rather than using an active interactive login. * **Company path**: The full path to the Sage 300 CRE company data folder. Example: ``` C:\\ProgramData\\Sage\\Timberline Office\\Data\\Construction Sample Data ``` * **tsObject.exe path**: Path to Timberline `tsObject.exe`, used for writing transactional and job-cost objects. The default install location is: ``` C:\\Program Files (x86)\\Timberline Office\\Shared\\tsObject.exe ``` Once you have these credentials, provide them to support. In return, you will get the connector file, which is an `exe` Windows program that you will run, and a connector password. ## Sample config Tenant config is stored in hotglue and pulled down by the connector on each cycle. A typical config looks like: ```json theme={null} { "company_path": "C:\\ProgramData\\Sage\\Timberline Office\\Data\\Construction Sample Data", "username": "", "password": "", "ts_object_exe": "C:\\Program Files (x86)\\Timberline Office\\Shared\\tsObject.exe", "read_frequency": 60, "tables": { "vendor": { "sync": true, "replication_key": ["VDSTMP", "VTSTMP"], "columns": ["VENDOR", "VNAME", "VDSTMP", "VTSTMP"] }, "job": { "sync": true, "replication_key": ["JDSTAMP", "JTSTAMP"] } } } ``` | Field | Required | Description | | :- | :- | :- | | `company_path` | Yes | Full path to the Sage 300 CRE company data folder. | | `username` | No | Sage username. Leave blank for open/sample companies. | | `password` | No | Sage password. Leave blank for open/sample companies. | | `ts_object_exe` | For most writes | Path to `tsObject.exe`. Defaults to the standard Timberline Shared folder. | | `read_frequency` | No | Seconds between read cycles. Defaults to `30`. | | `tables` | For read | Map of stream / table names to sync settings. Friendly names (for example `vendor`) or raw Sage ODBC table names are both valid. | ### Table options Each key under `tables` is either a friendly stream name (see [Read](#read)) or a raw Sage ODBC table name. | Field | Required | Description | | :- | :- | :- | | `sync` | Yes | Set to `true` to include the table in read syncs. | | `replication_key` | No | Column(s) used for incremental reads. Pass a string for a single column, or an array of columns (for example `["VDSTMP", "VTSTMP"]`). | | `columns` | Recommended | Explicit list of fields to sync. Sage tables often have 100+ columns; omitting this can make reads very slow. If you set a `replication_key`, include those columns here. Use Sage dictionary field names (for example `VENDOR`, `VNAME`). | ## Run the connector Now you have all you need to run the connector. 1. Download the [Connector launcher file](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/executables/Sage300CRE-HGConnector-Launcher.exe). > [!NOTE] > > The Sage 300 CRE connector is packaged as an `.exe` file. Read and write run in the same process. 2. Run the launcher `.exe` file as administrator. This registers the connector as a service and starts setup. 3. The connector will open a pop-up requesting your connector password. Enter your connector password and click OK. That's it. The connector is now running and ready to sync your Sage 300 CRE data. Config and logs live under `C:\Program Files (x86)\hotglue` by default. # Supported Objects ## Write The Sage 300 CRE connector supports writing the objects below. Writes are dispatched by the payload filename (for example `vendor.json` or `bill.json`). Objects are processed in dependency order: vendors and job-cost setup first, then journal entries, commitments, and bills. | Object | Payload file | Create | Update | | :- | :- | :- | :- | | Vendors | `vendor.json` | Yes | Yes | | Jobs | `job.json` | Yes | — | | Cost Codes | `cost_code.json` | Yes | — | | Categories | `category.json` | Yes | — | | Journal Entries | `journal_entry.json` | Yes | — | | Bills (AP invoices) | `bill.json` | Yes | — | | Commitments | `commitment.json` | Yes (including change orders) | Yes | > [!NOTE] > > In addition to the fields listed below, all objects support the optional `externalId` field. > This is used to associate the created record in Sage with your own id. This field is not mapped to Sage 300 CRE, and only persists within hotglue. > [!NOTE] > > When writing data to Sage 300 CRE, ensure that the `.json` files are written to the `etl-output` folder in your jobs. Otherwise the connector will not process them. The filename prefix must match the stream name exactly (for example `vendor.json`, not `vendors.json`). ### Vendors Payload file: `vendor.json` Vendors can be created or updated. Field names use Sage dictionary names. * Include `VRWID` to update a specific existing vendor by row id * Otherwise, if `VENDOR` already exists it is updated; if not, a new vendor is created | Field | Required | Description | | :- | :- | :- | | `VENDOR` | Yes (for create / update by vendor id) | Vendor ID. Max 10 characters. | | `VNAME` | Recommended | Vendor name. Max 30 characters. | | `VRWID` | For update by row id | Existing Sage row id | | `VADDR1` | No | Address line 1 | | `VADDR2` | No | Address line 2 | | `VCITY` | No | City | | `VSTATE` | No | State | | `VZIP` | No | ZIP / postal code | | `VCCODE` | No | Country code | | `VPHONE` | No | Telephone | | `VFAX` | No | Fax | | `VCNAME1` | No | Contact 1 name | | `VCTELE1` | No | Contact 1 telephone | | `VCEML1` | No | Contact 1 email | | `VTYPE` | No | Vendor type | | `VGLEXP` | No | Default expense account | Additional vendor fields are available — see the [AP vendor field list](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/ap-vendor-fields.pdf). > [accordion] Sample payload > > ```json theme={null} > [ > { > "externalId": "vendor-2000", > "VENDOR": "2000", > "VNAME": "Vendor 2000", > "VADDR1": "34092 Euclid Ave.", > "VADDR2": "", > "VCITY": "Cleveland", > "VSTATE": "OH", > "VZIP": "45800", > "VCCODE": "US", > "VPHONE": "(857) 555-0744", > "VFAX": "(857) 555-9999", > "VCNAME1": "John Doe", > "VCTELE1": "(857) 555-8888", > "VCEML1": "john.doe@example.com" > } > ] > ``` ### Jobs Payload file: `job.json` | Field | Required | Description | | :- | :- | :- | | `id` | Yes | Job ID. Must match the company's job format (for example `26-010`). | | `description` | Yes | Job description. | | `address.street` | No | Job street address | | `address.city` | No | City | | `address.state` | No | State | | `address.zip` | No | ZIP | | `customer.name` | No | Customer name on the job | | `customer.address.*` | No | Customer address fields | | `size.quantity` | No | Job size | | `size.unit` | No | Size unit (for example `sqft`) | > [accordion] Sample payload > > ```json theme={null} > [ > { > "externalId": "job-010", > "id": "26-010", > "description": "University Apartments", > "address": { > "street": "335 Spicer St.", > "city": "Akron", > "state": "OH", > "zip": "45904" > }, > "customer": { > "name": "MidWest RE", > "address": { > "street": "34092 Euclid Ave.", > "city": "Cleveland", > "state": "OH", > "zip": "45800" > } > }, > "size": { > "quantity": 150000, > "unit": "sqft" > } > } > ] > ``` ### Cost Codes Payload file: `cost_code.json` Cost codes belong to a job. The job must already exist, or be created in the same write job first. Set `extraId` to attach the cost code to a job extra. | Field | Required | Description | | :- | :- | :- | | `jobId` | Yes | Parent job ID | | `costCode` | Yes | Cost code. Must match the company's cost code format. | | `date` | Yes | Date. Accepts ISO `YYYY-MM-DD` or `MM/DD/YYYY`. | | `description` | No | Cost code description | | `extraId` | No | Parent extra ID | | `productionUnits.quantity` | No | Production units | | `productionUnits.unit` | No | Production unit of measure | > [accordion] Sample payload > > ```json theme={null} > [ > { > "externalId": "cost_code-001", > "jobId": "26-010", > "extraId": null, > "costCode": "3-104", > "description": "Concrete Forms", > "date": "2026-09-28", > "productionUnits": { > "quantity": 5, > "unit": "ea" > } > } > ] > ``` ### Categories Payload file: `category.json` Categories belong to a job and cost code. The parent job must already exist, or be created in the same write job first. | Field | Required | Description | | :- | :- | :- | | `jobId` | Yes | Parent job ID | | `costCode` | Yes | Cost code the category belongs to | | `date` | Yes | Date. Accepts ISO `YYYY-MM-DD` or `MM/DD/YYYY`. | | `category` | Recommended | Category code (for example `L`, `M`, `S`). Required when the company uses categories. | | `extraId` | No | Parent extra ID | | `estimatedUnits` | No | Estimated units. Defaults to `0`. | | `estimatedCost` | No | Estimated cost. Defaults to `0`. | > [accordion] Sample payload > > ```json theme={null} > [ > { > "externalId": "category-001", > "jobId": "26-010", > "extraId": null, > "costCode": "3-104", > "category": "L", > "date": "2026-09-28", > "estimatedUnits": 40.00, > "estimatedCost": 660.00 > } > ] > ``` ### Journal Entries Payload file: `journal_entry.json` Each entry must balance (total debits = total credits). Every line needs exactly one non-zero `debit` or `credit`. | Field | Required | Description | | :- | :- | :- | | `id` | Yes | Journal reference. Max 10 characters. Shared across all lines in the entry. | | `date` | Yes | Accounting date. Accepts ISO `YYYY-MM-DD` or `MM/DD/YYYY`. Must fall in an open period. | | `journal` | No | Journal number (max 2 digits) | | `description` | No | Entry description. Max 30 characters. Line-level values override this. | | `reference2` | No | Secondary reference. Max 10 characters. Line-level values override this. | | `basis` | Conditional | `"accrual"`, `"cash"`, or `null`. Required only when the company accounting method is Both. | | `lines` | Yes | Array of journal lines | | `lines[].account` | Yes | GL account | | `lines[].debit` | One of the two | Debit amount | | `lines[].credit` | One of the two | Credit amount | | `lines[].description` | No | Line description override | | `lines[].reference2` | No | Line reference override | | `lines[].basis` | No | Line basis override | > [!WARNING] > > Journal entries written through this stream do not update Job Cost. Use bills or other job-cost objects when the entry should hit a job, cost code, or category. > [accordion] Sample payload > > ```json theme={null} > [ > { > "externalId": "je-1003", > "id": "JE1003", > "date": "2022-07-28", > "journal": 21, > "description": "Insurance allocation", > "reference2": "ref2", > "basis": null, > "lines": [ > { > "account": "6200", > "debit": 400.00, > "credit": 0 > }, > { > "account": "6210", > "debit": 350.00, > "credit": 0 > }, > { > "account": "6220", > "debit": 250.00, > "credit": 0, > "reference2": "lineref2" > }, > { > "account": "1400", > "debit": 0, > "credit": 1000.00, > "description": "Prepaid insurance" > } > ] > } > ] > ``` ### Bills Payload file: `bill.json` #### Invoice header | Field | Required | Description | | :- | :- | :- | | `Vendor` | Yes | Vendor ID. Limited to 10 characters. | | `Invoice` | Yes | Invoice number. Limited to 15 characters. | | `Amount` | Yes | Invoice total. | | `Description` | No | Invoice description. Limited to 30 characters. | | `Tax` | No | Tax amount. | | `DiscountOffered` | No | Discount amount. | | `MiscDeduction` | No | Misc deduction. | | `InvoiceDate` | No | Invoice date. Accepts `MM/DD/YYYY` or ISO `YYYY-MM-DD`. | | `DateReceived` | No | Date received. | | `DiscountDate` | No | Discount date. | | `PaymentDate` | No | Payment date. | | `AccountingDate` | No | Accounting date. | | `InvoiceCode1` | No | Invoice code 1. | | `InvoiceCode2` | No | Invoice code 2. | | `SmryPayeeName` | No | Summary payee name. Limited to 30 characters. | | `SmryPayeeAddress1` | No | Payee address line 1. Limited to 33 characters. | | `SmryPayeeAddress2` | No | Payee address line 2. Limited to 33 characters. | | `SmryPayeeCity` | No | Payee city. Limited to 30 characters. | | `SmryPayeeState` | No | Payee state. Limited to 4 characters. | | `SmryPayeeZIP` | No | Payee ZIP. Limited to 10 characters. | | `distributions` | Yes | Array of distribution lines. At least one is required. | #### Distribution lines | Field | Required | Description | | :- | :- | :- | | `Amount` | Recommended | Distribution amount. | | `ExpenseAccount` | Recommended | Expense account. Limited to 14 characters. | | `APAccount` | No | Accounts payable account. Limited to 14 characters. | | `Job` | No | Job ID | | `Extra` | No | Extra | | `CostCode` | No | Cost code | | `Category` | No | Category | | `Commitment` | No | Commitment number | | `CommitmentLineItem` | No | Commitment line item | | `Units` | No | Units | | `UnitCost` | No | Unit cost | | `Retainage` | No | Retainage | | `1099Exempt` | No | 1099 exempt flag | | `DistCode` | No | Distribution code. Limited to 10 characters. | | `Description` | No | Line description. Limited to 30 characters. | | `Authorization` | No | Authorization. Limited to 10 characters. | | `JointPayee` | No | Joint payee. Limited to 30 characters. | | `Draw` | No | Draw | | `TaxGroup` | No | Tax group | | `Equipment` | No | Equipment | | `EQCostCode` | No | Equipment cost code | | `PMProperty` | No | Property. Limited to 10 characters. | | `PMUnit` | No | Unit. Limited to 10 characters. | | `PMLease` | No | Lease. Limited to 15 characters. | | `PMLeaseRevisionNum` | No | Lease revision number. | | `PMTenant` | No | Tenant. Limited to 10 characters. | | `PMChargeType` | No | Charge type. Limited to 10 characters. | | `PMChargeDate` | No | Charge date. | | `PMItemID` | No | Item ID. Limited to 20 characters. | | `PMChargebackDescription` | No | Chargeback description. Limited to 30 characters. | | `PMMarkupPercent` | No | Markup percent. | | `PMMarkupAmount` | No | Markup amount. | | `PMMarkupChargeType` | No | Markup charge type. Limited to 10 characters. | | `DefaultPaymentType` | No | Default payment type. | > [accordion] Sample payload > > ```json theme={null} > [ > { > "externalId": "bill-2003", > "Vendor": "2000", > "Invoice": "HG-TEST-2003", > "Description": "Hotglue import test", > "Amount": 500.0, > "InvoiceDate": "07/28/2026", > "DateReceived": "07/28/2026", > "AccountingDate": "07/28/2026", > "distributions": [ > { > "Job": "26-010", > "CostCode": "3-104", > "Category": "L", > "ExpenseAccount": "10-5100", > "Amount": 500.00, > "1099Exempt": "t", > "DistCode": "parts" > } > ] > } > ] > ``` ### Commitments Payload file: `commitment.json` Commitments support create, change orders, and updates to existing commitments. #### Create a commitment Use `type: "subcontract"` for a new commitment. | Field | Required | Description | | :- | :- | :- | | `number` | Yes | Commitment number | | `type` | Yes | Commitment type. Use `subcontract`. | | `description` | Yes | Commitment description | | `date` | Yes | Commitment date. Accepts ISO `YYYY-MM-DD` or `MM/DD/YYYY`. | | `vendor.id` | Yes | Vendor ID | | `project.number` | Yes | Job / project number | | `status` | No | Status. Use `executed` for an executed commitment. | | `retainage_percent` | No | Retainage percent | | `items` | Yes | Commitment line items. At least one is required. | | `items[].number` | Yes | Line item number | | `items[].description` | Yes | Line description | | `items[].cost_code` | Yes | Cost code | | `items[].category` | Yes | Category | | `items[].amount` | Yes | Line amount | | `items[].project.number` | No | Overrides the header project for this line | > [accordion] Sample payload (new commitment) > > ```json theme={null} > [ > { > "externalId": "commitment-2000", > "number": "CO-2000", > "type": "subcontract", > "description": "Interior Painting", > "status": "executed", > "date": "2026-09-15", > "retainage_percent": 10.0, > "project": { > "number": "26-010", > "name": "University Apartments" > }, > "vendor": { > "id": "2000", > "name": "Vendor 2000" > }, > "items": [ > { > "number": 1, > "description": "Mobilization and prep", > "cost_code": "3-104", > "category": "L", > "amount": 8500.00 > }, > { > "number": 2, > "description": "Interior finish painting", > "cost_code": "3-104", > "category": "L", > "amount": 40000.00 > } > ], > "total": 48500.00 > } > ] > ``` #### Change orders Send `type: "change_order"` against an existing commitment. | Field | Required | Description | | :- | :- | :- | | `number` | Yes | Change order number | | `type` | Yes | Must be `change_order` | | `description` | Yes | Change order description | | `commitment.number` | Yes | Existing commitment number | | `date` | No | Change order date | | `status` | No | `not_issued`, `pending`, `approved`, or `denied` | | `items` | Yes | Change order lines | | `items[].commitment_item` / `items[].number` | Yes | Commitment line item number | | `items[].amount` | Yes | Amount | | `items[].description` | No | Line description | | `items[].units` | No | Units | > [accordion] Sample payload (change order) > > ```json theme={null} > [ > { > "number": "001", > "type": "change_order", > "description": "Added scope", > "status": "approved", > "date": "2022-05-20", > "commitment": { > "number": "HG0001", > "description": "Job Signage" > }, > "items": [ > { > "commitment_item": 1, > "description": "Additional painting", > "amount": 750.00 > } > ], > "total": 750.00 > } > ] > ``` #### Update an existing commitment To update an existing commitment, send the lookup key plus the fields to change: * `SRWID` to update by Sage row id, or * `SUB` to update by commitment number | Field | Required | Description | | :- | :- | :- | | `SRWID` | For update by row id | Existing Sage row id | | `SUB` | For update by commitment number | Commitment number | | *(other fields)* | Yes (at least one) | Fields to update (for example `SDESC` for description) | > [accordion] Sample payload (update) > > ```json theme={null} > [ > { > "externalId": "commitment-2307", > "SRWID": "eaa28b63-ee3f-e711-8bef-0019b9211094", > "SDESC": "Updated by row id" > }, > { > "externalId": "commitment-2308", > "SUB": "2308", > "SDESC": "Updated by commitment number" > } > ] > ``` ## Read Read syncs any table you enable under `tables`. You are not limited to a fixed catalog — the connector can query **any table** exposed by the Sage 300 CRE ODBC database. Configure reads with either: 1. **Friendly stream names** (recommended for common objects) 2. **Raw Sage ODBC table names** when you need something outside the aliases below Field names in results (and in `columns` / `replication_key`) use Sage dictionary names (for example `VENDOR`, `VNAME`, `VDSTMP`). ### Common stream aliases | Stream | Suggested `replication_key` | Field reference | | :- | :- | :- | | `account` | `["ADSTMP", "ATSTMP"]` | [GL accounts](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/gl-accounts.pdf) | | `vendor` | `["VDSTMP", "VTSTMP"]` | [AP vendors](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/ap-vendor-fields.pdf) | | `job` | `["JDSTAMP", "JTSTAMP"]` | [JC jobs](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/jc-job-fields.pdf) | | `cost_code` | `["PDSTAMP", "PTSTAMP"]` | [JC cost codes](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/jc-cost-code-fields.pdf) | | `standard_cost_code` | `["SPDSTMP", "SPTSTMP"]` | [JC standard cost codes](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/jc-standard-cost-code-fields.pdf) | | `category` | `["CDSTAMP", "CTSTAMP"]` | [JC categories](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/jc-category-fields.pdf) | | `standard_category` | `["SCDSTMP", "SCTSTMP"]` | [JC standard categories](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/jc-standard-category-fields.pdf) | | `journal_entry` | `["TDSTMP", "TTSTMP"]` | [GL journal entries](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/gl-journal-entry-fields.pdf) | | `ar_transaction` | `["TDSTAMP", "TTSTAMP"]` | [AR transactions](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/ar-transactions-fields.pdf) | | `ap_transaction` | `["TDSTAMP", "TTSTAMP"]` | [AP transactions](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/ap-transaction-fields.pdf) | | `invoice_payment` | `["PIDSTMP", "PITSTMP"]` | [Invoice Payments](https://s3.us-east-1.amazonaws.com/cdn.hotglue.xyz/docs/ap-invoice-payments-fields.pdf) | Use the field-reference PDFs to pick `columns` and understand stamp / id fields. To sync any other table, use its Sage ODBC table name as the `tables` key — contact support if you need help identifying the right fields. > [accordion] Example table config > > ```json theme={null} > { > "tables": { > "vendor": { > "sync": true, > "replication_key": ["VDSTMP", "VTSTMP"], > "columns": ["VENDOR", "VNAME", "VADDR1", "VCITY", "VSTATE", "VZIP", "VDSTMP", "VTSTMP", "VRWID"] > }, > "job": { > "sync": true, > "replication_key": ["JDSTAMP", "JTSTAMP"] > }, > "ap_transaction": { > "sync": true, > "replication_key": ["TDSTAMP", "TTSTAMP"] > } > } > } > ``` > [!TIP] > > If you omit `columns`, reads can be very slow on Sage tables with a large number of fields. Prefer listing only the fields you need. # Sage 50 UK Source: https://docs.hotglue.com/connectors/sage-50 # Connector Details | Name | Value | | :- | :- | | Platform | Sage 50 UK | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (low) | # Tenant setup guide Use the guide below to guide your users on how to configure the Sage 50 connector. ## Initial credential configuration Before installing the connector locally, you will need to gather your credentials: * **Username and password**: You will need to create a user reserved for this integration. This is because the connector is not allowed to run by Sage if its user is logged in, so if you use the username and password for an active user, the connector will not run. To create a new user: * Log in as the admin (MANAGER) * Go to Settings > User Management > Users * Click New, and create a new user. * **DSN**: Sage data is stored in an underlying database, which the connector uses to read data from Sage. Sage 50 comes pre-installed with a DSN pointing to the underlying database. This default DSN looks like `SageLine50v29`, where `29` is your version of Sage. To confirm your DSN is present and accessible: * Click the Search button on the bottom left of your Windows toolbar * Search for `ODBC` and Select `ODBC Data Sources (64-bit)` * Click `System DSN`. You should see a DSN starting with `SageLine50` that matches your version. This is the proper DSN name to configure your connector. * If you'd like to create a new DSN (not required), you can follow [this walkthrough](https://www.youtube.com/watch?v=iJBrTkCkkX0) to generate a new DSN. * **Company file path**: This will be the full file path to your Sage 50 program data, ending in `accdata`. You can find your company file path from inside Sage: * Log into Sage, and navigate to `Help` > `About` on the top bar. * In the top left Program Details section, there is a `Data Directory` file path. Click that link. * This will take you to your Sage program folder, which should contain an `accdata` folder. * Click into `accdata`. You can then select the ribbon at the top, and copy-paste your company file path. It should look something like the below: ``` C:\\ProgramData\\Sage\\Accounts\\2024\\DemoData\\accdata ``` Once you have these credentials, provide them to support. In return, you will get the connector file, which is an `exe` windows program that you will run, and a connector password. ## Run the connector Now you have all you need to run the connector. 1. Download the Connector launcher file. > [!NOTE] > > The Sage 50 connector is packaged as an .exe file. 2. Run the launcher `.exe` file. This will automatically register the connector as a service and kick off the setup process. 3. The connector will open a pop-up requesting your connector password. Enter your connector password and click OK. That's it! Your connector is now running and ready to sync your Sage data. # Supported Objects ## Write The Sage 50 connector supports writing of several objects out of the box. The expected payloads and mappings are documented below. > [!NOTE] > > In addition to the fields listed below, all objects support the optional `externalid` field. \\ > > This is used to associate the created record in Sage with your own id. This field is not mapped to Sage 50, and only persists within hotglue. ### Products Payload file: `products.json` | Field | Description | | - | - | | `stock_code` | Unique product stock code | | `description` | Product description | | `nominal_code` | Nominal code | | `unit_of_sale` | Unit of sale (e.g. `Each`) | > [accordion] Sample payload > > ```json theme={null} > [ > { > "stock_code": "FIFA25", > "description": "FIFA 2025 Edition", > "nominal_code": "4000", > "unit_of_sale": "Each" > } > ] > ``` ### Vendors Payload file: `vendors.json` | Field | Description | | - | - | | `account_ref` | The unique account ref for this vendor, will be used for referencing this vendor in transactions. Limited to 8 characters. | | `name` | Name of the vendor | | `address_1` | Address line 1 | | `address_2` | Address line 2 | | `address_3` | Address line 3 | | `address_4` | Address line 4 | | `address_5` | Address line 5 | | `contact_name` | Vendor contact name | | `telephone` | Telephone Number | | `fax` | Fax Number | | `analysis_1` | | | `analysis_2` | | | `analysis_3` | | | `terms` | | | `def_nom_code` | Default nominal code for transactions | | `vat_reg_number` | Vendor VAT number | | `country_code` | Country code | | `currency` | Currency code for this vendor (e.g. `GBP`) | > [accordion] Sample payload > > ```json theme={null} > [ > { > "account_ref": "2", > "name": "NVIDIA", > "address_1": "2788 San Tomas Expy", > "address_2": "Santa Clara, CA 95051", > "contact_name": "Jensen Huang", > "telephone": "408 486 2000" > } > ] > ``` ### Customers Payload file: `customers.json` | Field | Description | | - | - | | `account_ref` | The unique account ref for this customer, will be used for referencing this customer in transactions. Limited to 8 characters. | | `name` | Name of the customer | | `address_1` | Address line 1 | | `address_2` | Address line 2 | | `address_3` | Address line 3 | | `address_4` | Address line 4 | | `address_5` | Address line 5 | | `contact_name` | Customer contact name | | `telephone` | Telephone Number | | `fax` | Fax Number | | `analysis_1` | | | `analysis_2` | | | `analysis_3` | | | `terms` | | | `def_nom_code` | Default nominal code for transactions | | `vat_reg_number` | Customer VAT number | | `country_code` | Country code | | `currency` | Currency code for this customer (e.g. `GBP`) | > [accordion] Sample payload > > ```json theme={null} > [ > { > "account_ref": "2", > "name": "NVIDIA", > "address_1": "2788 San Tomas Expy", > "address_2": "Santa Clara, CA 95051", > "contact_name": "Jensen Huang", > "telephone": "408 486 2000" > } > ] > ``` ### VendorInvoices Payload file: `vendorinvoices.json` | Field | Description | | - | - | | `account_ref` | Account ref of the vendor associated with this invoice | | `date` | Date of invoice | | `posted_date` | Posted date of invoice | | `date_due` | Due date of invoice | | `inv_ref` | Invoice ref number | | `tax_amount` | Tax amount | | `discount` | Discount amount | | `discount_nominal_code` | Discount nominal code | | `items` | Array of line items (see below for line item fields) | | `items.nominal_code` | Nominal code | | `items.tax_code` | Tax code | | `items.net_amount` | Net amount | | `items.tax_amount` | Tax amount | | `items.details` | Description of line item | | `items.project_id` | Project ID | | `items.department_id` | Department ID | | `items.cost_code` | Cost Code | > [accordion] Sample payload > > ```json theme={null} > [ > { > "account_ref": "1", > "externalid": "89979", > "date": "2025-01-31T00:00:00.000Z", > "posted_date": "2025-01-31T15:06:45.000Z", > "date_due": "2025-02-14T00:00:00.000Z", > "inv_ref": "HGT-3", > "currency": "GBP", > "items": [ > { > "nominal_code": "4000", > "net_amount": 44.50, > "details": "22 Bananas" > }, > { > "nominal_code": "4000", > "net_amount": 22.00, > "details": "11 Pears" > } > ] > } > ] > ``` ### CustomerInvoices Payload file: `customerinvoices.json` | Field | Description | | - | - | | `account_ref` | Account ref of the customer associated with this invoice | | `date` | Date of invoice | | `posted_date` | Posted date of invoice | | `date_due` | Due date of invoice | | `inv_ref` | Invoice ref number | | `tax_amount` | Tax amount | | `discount` | Discount amount | | `discount_nominal_code` | Discount nominal code | | `items` | Array of line items (see below for line item fields) | | `items.nominal_code` | Nominal code | | `items.tax_code` | Tax code | | `items.net_amount` | Net amount | | `items.tax_amount` | Tax amount | | `items.details` | Description of line item | | `items.project_id` | Project ID | | `items.department_id` | Department ID | | `items.cost_code` | Cost Code | > [accordion] Sample payload > > ```json theme={null} > [ > { > "account_ref": "1", > "externalid": "89979", > "date": "2025-01-31T00:00:00.000Z", > "posted_date": "2025-01-31T15:06:45.000Z", > "date_due": "2025-02-14T00:00:00.000Z", > "inv_ref": "HGT-3", > "currency": "GBP", > "items": [ > { > "nominal_code": "4000", > "net_amount": 44.50, > "details": "22 Bananas" > }, > { > "nominal_code": "4000", > "net_amount": 22.00, > "details": "11 Pears" > } > ] > } > ] > ``` ### CustomerNotes Payload file: `customernotes.json` | Field | Description | | - | - | | `account_ref` | Account ref of the customer associated with this credit note | | `date` | Date of credit note | | `posted_date` | Posted date of credit note | | `inv_ref` | Credit note ref number | | `tax_amount` | Tax amount | | `items` | Array of line items (see below for line item fields) | | `items.nominal_code` | Nominal code | | `items.tax_code` | Tax code | | `items.net_amount` | Net amount | | `items.tax_amount` | Tax amount | | `items.details` | Description of line item | | `items.project_id` | Project ID | | `items.department_id` | Department ID | | `items.cost_code` | Cost Code | > [accordion] Sample payload > > ```json theme={null} > [ > { > "account_ref": "1", > "externalid": "1616", > "date": "2025-01-31T00:00:00.000Z", > "posted_date": "2025-01-31T15:06:45.000Z", > "inv_ref": "CRED001", > "currency": "GBP", > "items": [ > { > "nominal_code": "4000", > "net_amount": 50, > "details": "Credit Note for Jan" > } > ] > } > ] > ``` ## Read > [accordion] Supported objects for read > > ## Audit Trail (Transactions) > > * **Audit - Header**: `AUDIT_HEADER` > * **Audit - Journal**: `AUDIT_JOURNAL` > * **Audit - Split**: `AUDIT_SPLIT` > * **Audit - Usage**: `AUDIT_USAGE` > * **Audit - VAT**: `AUDIT_VAT` > * **Audit History - Header**: `AUDIT_HISTORY_HEADER` > * **Audit History - Journal**: `AUDIT_HISTORY_JOURNAL` > * **Audit History - Split**: `AUDIT_HISTORY_SPLIT` > * **Audit History - Usage**: `AUDIT_HISTORY_USAGE` > * **Clear Audit Trail Event**: `CLEAR_AUDIT_TRAIL_EVENT` > * **Cleared Transaction Range**: `CLEARED_TRAN_RANGE` > * **Deleted Records**: `DELETED_RECORDS` > * **Dispute Reason**: `DISPUTE_REASON` > > ## Bank > > * **Bank**: `BANK` > * **Bank Statement**: `BANK_STATEMENT` > * **Bank Statement - Line**: `BANK_STATEMENT_LINE` > * **Recurring Entries**: `RECURRING` > * **Remittance**: `REMITTANCE` > > ## Calendar > > * **Calendar Event**: `CALENDAR_EVENT` > * **Calendar Event - Label**: `CALENDAR_EVENT_LABEL` > * **Calendar Event - Location**: `CALENDAR_EVENT_LOCATION` > * **Calendar Event - Recurrence Pattern**: `CALENDAR_EVENT_RECURRENCE_PATTERN` > > ## Category > > * **Category**: `CATEGORY` > * **Category - Title**: `CAT_TITLE` > > ## Charities/Funds > > * **Fund**: `FUND` > * **Fund Type**: `FUND_TYPE` > * **SOFA (Statement of Financial Activities) Category**: `SOFA_CATEGORY` > > ## CIS (Construction Industry Scheme) > > * **CIS Return**: `CIS_RETURN` > * **CIS Return - Transactions**: `CIS_RETURN_TRANSACTION` > * **CIS Settings**: `CIS_SETTINGS` > * **CIS Subcontractor**: `CIS_SUBCONTRACTOR` > * **CIS Subcontractor - Legacy**: `CIS_SUBCONTRACTOR_LEGACY` > * **CIS Subcontractor - Return**: `CIS_SUBCONTRACTOR_RETURN` > * **CIS Subcontractor - Tax History**: `CIS_SUBCONTRACTOR_TAX_HISTORY` > > ## Company > > * **Company**: `COMPANY` > * **Company Delivery Address**: `COMPANY_DEL_ADDR` > > ## Contact History > > * **Contact History**: `CONTACT_HISTORY` > * **Contact History - Major Type**: `CONTACT_HISTORY_MAJOR_TYPE` > * **Contact History - Contact Outcome**: `CONTACT_HISTORY_CONTACT_OUTCOME` > * **Contact History - Contact Type**: `CONTACT_HISTORY_CONTACT_TYPE` > > ## International > > * **EC Sales - Fill**: `ECSALES_FILL` > * **EC Sales - Header**: `ECSALES_HEADER` > * **EC Sales - Split**: `ECSALES_SPLIT` > * **EC Sales - VAT Description**: `EC_VAT_DESCRIPTION` > * **Intrastat**: `INTRASTAT` > > ## Invoice > > * **Invoice**: `INVOICE` > * **Invoice - Item**: `INVOICE_ITEM` > * **Update Ledgers**: `UPDATE_LEDGER` > > ## Multi-use/Miscellaneous > > * **Account Status**: `ACCOUNT_STATUS` > * **Communication Address**: `COMMUNICATION_ADDRESS` > * **Country Code**: `COUNTRY_CODE` > * **Currency**: `CURRENCY` > * **Department**: `DEPARTMENT` > * **Letter Type**: `LETTER_TYPE` > * **Price**: `PRICE` > * **Price List**: `PRICE_LIST` > * **Tax Code**: `TAX_CODE` > > ## Nominal > > * **Accrual**: `ACCRUAL` > * **Chart of Accounts**: `CHART_LIST` > * **Financial Budget**: `FINANCIAL_BUDGET` > * **Fixed Assets**: `FIXED_ASSET` > * **Fixed Assets - Category**: `FIXED_ASSET_CAT` > * **Nominal Ledger**: `NOMINAL_LEDGER` > * **Period Values**: `PERIOD` > * **Prepayments**: `PREPAYMENT` > > ## Payment > > * **Payment Information**: `PAYMENT_INFO` > * **Payment Method**: `PAYMENT_METHOD` > * **ProTX Payment**: `PROTX_PAYMENT` > * **Supplier Payment Info**: `SUPPLIER_PAYMENT_INFO` > > ## Projects > > * **Project**: `PROJECT` > * **Project - Budget**: `PROJECT_BUDGET` > * **Project - Cost Code**: `PROJECT_COST_CODE` > * **Project - Cost Type**: `PROJECT_COST_TYPE` > * **Project - Only Transactions**: `PROJECT_ONLY_TRAN` > * **Project - Relationship**: `PROJECT_RELATIONSHIP` > * **Project - Resource**: `PROJECT_RESOURCE` > * **Project - Resource Type**: `PROJECT_RESOURCE_TYPE` > * **Project - Revenue Code**: `PROJECT_REVENUE_CODE` > * **Project - Status**: `PROJECT_STATUS` > * **Project - Transactions**: `PROJECT_TRAN` > > ## Purchase Ledger (Suppliers) > > * **Goods Received Note Items (GRN)**: `GRN_ITEM` > * **Purchase Delivery Address**: `PURCHASE_DEL_ADDR` > * **Purchase Ledger (Suppliers)**: `PURCHASE_LEDGER` > * **Purchase Order**: `PURCHASE_ORDER` > * **Purchase Order Items**: `POP_ITEM` > * **Supplier Payment Info**: `SUPPLIER_PAYMENT_INFO` > > ## Sales Ledger (Customers) > > * **Credit Bureau**: `CREDIT_BUREAU` > * **Direct Debit Payment Requests**: `DIRECT_DEBIT_PAYMENT_REQUESTS` > * **Goods Despatched Note Items (GDN)**: `GDN_ITEM` > * **Payment Information**: `PAYMENT_INFO` > * **Sagepay - Pay-by Link**: `SAGEPAY_PAY_BY_LINK` > * **Sales Delivery Address**: `SALES_DEL_ADDR` > * **Sales Ledger (Customers)**: `SALES_LEDGER` > * **Sales Order**: `SALES_ORDER` > * **Sales Order Items**: `SOP_ITEM` > > ## Stock > > * **Stock**: `STOCK` > * **Stock - Allocation**: `STOCK_ALLOCATION` > * **Stock - Category**: `STOCK_CAT` > * **Stock - Component**: `STOCK_COMP` > * **Stock - Transactions**: `STOCK_TRAN` > > ## VAT > > * **eSubmission Settings**: `ESUBMISSION_SETTINGS` > * **Return of Trading Details (RTD) Summary**: `RTD_SUMMARY` > * **VAT - Adjustment**: `VAT_ADJUSTMENT` > * **VAT - Details**: `VAT_DETAILS` > * **VAT - Reverse Charge - Details**: `VAT_REV_CHARGE_DETAIL` > * **VAT - Reverse Charge - Header**: `VAT_REV_CHARGE_HEADER` > * **VAT - Reverse Charge - Return**: `VAT_REV_CHARGE_RETURN` > * **VAT - VAT Summary**: `VAT_SUMMARY` > * **VAT - VAT Return**: `VAT_RETURN` > * **VAT - VAT Return Receipt**: `VAT_RETURN_RECEIPT` # Sage 300 Source: https://docs.hotglue.com/connectors/sage300 # Connector Details | Name | Value | | :- | :- | | Platform | [Sage 300](https://api) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-sage300](https://gitlab.com/hotglue/tap-sage300) | | Target Repo | [https://gitlab.com/hotglue/target-sage300](https://gitlab.com/hotglue/target-sage300) | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (low) | Sage 300 is a mid-market ERP for growing businesses, offering core financials, inventory, purchasing, and order management, with strong multi-company and multi-currency support. hotglue supports both reading and writing from Sage 300 instances. To enable the Sage 300 API, your tenants first need to install [WebScreens](https://help.sage300.com/en-us/2025/web/Content/Installation/InstallingWebScreens.htm) on their Sage 300 instance. In addition to allowing them to access Sage 300 via a web browser, this will also enable the Sage 300 API. To connect Sage 300, you'll first need to retrieve a `username` and `password` for a user on the Sage 300 instance. We recommend tenants create a dedicated Sage 300 user for their integration. You will also need the `company_id` that the integration should connect to. Next, note the URL of your WebScreens. This should be entered as the `host_app_path` in hotglue. Finally, enter the App Module based on what module you have enabled and plan to integrate with. The options are: * `AP`: Accounts Payable * `AR`: Accounts Receivable * `GL`: General Ledger # Salesforce Source: https://docs.hotglue.com/connectors/salesforce # Connector Details | Name | Value | | :- | :- | | Platform | [Salesforce](https://salesforce.com) | | Auth Type | OAuth or Client Credentials | | Direction | Bidirectional | | Triggers | Supported (3 triggers available by default) | | Tap Repo | [https://github.com/hotgluexyz/tap-salesforce](https://github.com/hotgluexyz/tap-salesforce) | | Target Repo | [https://github.com/hotgluexyz/target-salesforce-v3](https://github.com/hotgluexyz/target-salesforce-v3) | | Tap Metrics | Usage: (high) | | Target Metrics | Usage: (medium) | | Unified Schema | Supported in [Sales Unified Schema](https://hotglue.com/docs/unified). (Supported tables: Activities, Contacts, Companies, Deals, Users, Lists) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Credentials Setup - How to create a Salesforce Connected App There are two separate authentication flows available for the Salesforce connector: * [OAuth](#oauth-flow). * [Client Credentials](#client-credentials-flow). Use only the section that matches your authentication flow. The steps below cover both OAuth flow and Client Credentials flow. # OAuth flow Follow the steps below to get the credentials you need to use the Salesforce connector. The first thing you need to do is go ahead and log in to [Salesforce](https://login.salesforce.com). Once you are logged in and on the home page, navigate to your **Setup Menu**: ![Navigate to the SF Setup Menu](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/SFSetupMenu.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=8283b44db86b5d44c166b429ac447904) From your **Setup Menu** go to the left side of the page and select the Apps dropdown. Then, you should go ahead and click on the **Platform Tools** > **External Client Apps** > **Settings** section from the dropdown. ![Navigate to the External Client App Settings](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/SFExternalClientAppSettings.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=cc45eb5ad9ef4bc1974ab32faa330681) Now on this page, you should enable **Allow creation of connected apps** and click **New Connected App**: ![Create a new External Client App](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/CreateConnectedApp.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=4ebae7871f58e7162ad392175d11ef3e) On this page, you should name your OAuth app, put your email as the contact email, and then check the box **Enable OAuth Settings**. Now that you have enabled OAuth Settings, you should set the callback URL to ```text theme={null} https://hotglue.xyz/callback ``` Under **Security**, disable `Require Proof Key for Code Exchange (PKCE) Extension for Supported Authorization Flows`. You should also make sure that for the Selected OAuth Scopes, you have enabled the scopes for: 1. `Access and manage your data (api)` 2. `Perform request on your behalf at any time (refresh\\_token, offline\\_access)` ![Enable Salesforce Permissions](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/SFOAuthSettings.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=36d1314c0bd27764c2a15895487886b1) Once you have finished configuring the app, you should go ahead and click Save. Next, in **OAuth Settings** dropdown for your app, you'll find a button called **Manage Consumer Details**: ![Find SF Consumer Key and Secret](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/SFFindConsumerKeyAndSecret.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=6d166ed79636e216938c33a2171157b6) Now, you should copy these keys into hotglue, and you will be all good to go to start using the Salesforce source in hotglue. ![](https://files.readme.io/94a53a1-image.png) And that is it! You have now successfully linked to Salesforce! # Client Credentials flow The Client Credentials flow signs in as the app, not a user. It doesn't require a user login or refresh token. Unlike the OAuth flow, this involves the end user creating their own app in their Salesforce org. > [!WARNING] > > As of Spring '26, Salesforce disables the creation of new Connected Apps by default for all orgs. External Client Apps are the supported way to set up the Client Credentials flow. Steps to follow are: 1. Log in to [Salesforce](https://login.salesforce.com) and navigate to the **Setup Menu**. 2. Go to **Platform Tools** > **Apps** > **External Client Apps** > **External Client App Manager** and select **New External Client App**. To set up the flow on an app that already exists, find it in the list instead and select **Edit Settings** from its row dropdown. ![Edit Settings for an External Client App](https://mintcdn.com/hotglue/gafo-U0ut5wO6X9S/connectors/images/SFClientCredentialsECAEditSettings.png?fit=max\&auto=format\&n=gafo-U0ut5wO6X9S\&q=85\&s=2d7f4d87d65700aef9a4b3892faec824) 3. Name the app and enter a contact email. 4. On the **Settings** tab, expand the **OAuth Settings** section and enable OAuth. Set the **Callback URL** to `https://hotglue.xyz/callback`, and move `Manage user data via APIs (api)` into **Selected OAuth Scopes**. ![Expand OAuth Settings on the Settings tab](https://mintcdn.com/hotglue/gafo-U0ut5wO6X9S/connectors/images/SFClientCredentialsECAOAuthSettings.png?fit=max\&auto=format\&n=gafo-U0ut5wO6X9S\&q=85\&s=f52acca1961666036bb6682cd7b5ba40) 5. Scroll down to **Flow Enablement**, check **Enable Client Credentials Flow**, and select **Save**. ![Enable the Client Credentials Flow under Flow Enablement](https://mintcdn.com/hotglue/gafo-U0ut5wO6X9S/connectors/images/SFClientCredentialsECAEnableFlow.png?fit=max\&auto=format\&n=gafo-U0ut5wO6X9S\&q=85\&s=8ff93b718af111b6ede7af1e216594a3) 6. Open the app's **Policies** tab and select **Edit**. ![Open the Policies tab for the External Client App](https://mintcdn.com/hotglue/gafo-U0ut5wO6X9S/connectors/images/SFClientCredentialsECAPolicies.png?fit=max\&auto=format\&n=gafo-U0ut5wO6X9S\&q=85\&s=4fb4069c293ea84d47df07c3aa797626) 7. Expand **OAuth Policies**, and under **OAuth Flows and External Client App Enhancements** check **Enable Client Credentials Flow** and set **Run As (Username)** to an integration or administrator user. Select **Save**. ![Set the Run As user under OAuth Policies](https://mintcdn.com/hotglue/gafo-U0ut5wO6X9S/connectors/images/SFClientCredentialsECARunAs.png?fit=max\&auto=format\&n=gafo-U0ut5wO6X9S\&q=85\&s=88458a3aba051577b192852394636634) > [!NOTE] > > External Client Apps split these settings across two screens, and both must be set: **Settings** > **OAuth Settings** > **Flow Enablement** turns the flow on, and **Policies** > **OAuth Policies** turns it on again and holds the **Run As (Username)**. Salesforce rejects the token request with `no client credentials user enabled` if the Run As user is missing. > [!NOTE] > > The **Run As** user governs what the sync can see. Any object or field that user cannot read will not appear during discovery or sync, so make sure they have access to the required objects along with the [Required Tenant Permissions](#required-tenant-permissions). 8. Wait a few minutes for the changes to propagate, then use **Consumer Key and Secret** under **OAuth Settings** > **App Settings** to copy the **Consumer Key** and **Consumer Secret**. 9. Retrieve the org's My Domain URL from **Setup** > **Company Settings** > **My Domain** > **Current My Domain URL**. It looks like `https://mycompany.my.salesforce.com`. ## Enabling the Client Credentials Salesforce connector in hotglue Add the Salesforce source to a new or existing flow. Because each tenant authenticates with their own External Client App, no partner-level credentials are needed in this step. ## Tenant registration with Client Credentials When your tenants link their Salesforce accounts, they'll need to enter the following information: * `Consumer Key`: Use the **Consumer Key** from their External Client App. * `Consumer Secret`: Use the **Consumer Secret** from their External Client App. * `Instance URL`: Use the org's **Current My Domain URL**, for example `https://mycompany.my.salesforce.com`. # Required Tenant Permissions The authenticated tenant must have the following System Permissions on their Salesforce Instance: 1. `API Enabled` 2. `View Setup and Configuration` See the [Salesforce docs](https://help.salesforce.com/s/articleView?id=xcloud.branded_apps_commun_api_permset.htm\&type=5) for how to add these permissions to a permission set. If you plan on [enabling Salesforce's Bulk API](/connectors/salesforce#salesforce-bulk-api), your tenant also needs the system permission named `Manage Data Integrations`. # Allowing tenants to link Salesforce Sandbox Instances The OAuth Authentication flow for Salesforce Sandbox instances is slightly different from production Salesforce instances. As such, you'll need to add the `Salesforce:sandbox` connector as a supported source to your desired flows. **Tenants using sandbox Salesforce credentials must link to this source, not the normal Salesforce source.** > Production Salesforce OAuth apps are compatible with sandbox credentials, so you can reuse the same client ID and secret for both supported sources. ![Separate Salesforce and SF Sandbox sources](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/SFSandboxSupportedSource.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=0ec6a9948a077ea148276b325a5f0cd8) # API Quota Management Salesforce enforces strict daily API limits for every connected Salesforce instance. While the [specific request quota differs by Salesforce plan](https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_api.htm), hotglue's Salesforce connector works around these quotas to prevent eating up your tenants' allotments. ### How hotglue stops you from exceeding Salesforce quotas By default, a single hotglue job (or discover) will never use up **more than 25% of a tenant's Salesforce API quota**. Additionally, hotglue jobs will never make a request on your tenant's Salesforce account **if making that request would bring the tenant to 80% of their daily quota**. These thresholds can be customized by using the `quota_percent_per_run` and `quota_percent_total` config flags respectively on a tenant's linked Salesforce source. ### Salesforce Bulk API To further minimize Salesforce requests, you can enable the Salesforce bulk API for a tenant using the `"api_type": "BULK"` config flag. ### Incremental Syncs To prevent re-querying the same data, hotglue's Salesforce connector will only sync data that has been changed since the last successful hotglue job. ### Usage Logging After making a request, hotglue's Salesforce connector will log how many remaining requests are in a tenant's daily allotment. You can check the usage logs on the hotglue dashboard's job page. # Campaign, ListView, and Report Filtering Your tenants may be interested in only syncing Contacts and Leads that belong to certain Campaigns, Listviews, or Reports. If so, you can add any of the following `filters` to your Salesforce [available source](http://localhost:3000/key-concepts/connectors/v1-sources/overview#what-is-an-available-source): ```json theme={null} "filters": [ { "label": "Campaigns", "description": "The campaigns to sync", "type": "multiselect", "key": "campaigns", "sf_object": "Campaign", "targetKey": "campaign_ids" }, { "label": "Lists", "description": "The lists to sync", "type": "multiselect", "key": "lists", "sf_object": "ListView", "targetKey": "list_ids" }, { "label": "Reports", "description": "The reports to sync", "type": "multiselect", "key": "reports", "targetKey": "report_ids" } ] ``` During the widget linking process, the tenant will be given dropdowns for the filters you specify. During the syncing process, hotglue will only fetch Contacts and Leads according to these filters. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.5.6](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.5.6) | | > | [v1.5.4](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.5.4) | | > | [v1.5.2](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.5.2) | | > | [v1.5.1](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.5.1) | | > | [v1.5.0](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.5.0) | | > | [v1.4.44](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.4.44) | | > | [v1.4.43](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.4.43) | | > | [v1.4.42](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.4.42) | | > | [v1.4.41](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.4.41) | | > | [](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.4.40) | | > | [v1.4.39](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.4.39) | | > | [v1.4.38 - Bug fixes](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.4.38) | - Avoid validating JSON for non-JSON queries | > | [v1.4.37 - Minor bug fixes](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.4.37) | - Updated query to avoid cloning duplicate records - Updated `backoff` settings to prevent raising errors when retries work successfully | > | [v1.4.36 - Handle ListViews out of memory](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.4.36) | Fix issue created by holding ListView data in memory | > | [v1.4.35 - Support ListView details](https://github.com/hotgluexyz/tap-salesforce/releases/tag/v1.4.35) | Now pulling entries within each `ListView` by running queries when ListView is fetched as independent stream. | # Salesforce Commerce Cloud Source: https://docs.hotglue.com/connectors/salesforce-commerce # Connector Details | Name | Value | | :- | :- | | Platform | [Salesforce Commerce Cloud](https://demandware.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-salesforce-commerce](https://github.com/hotgluexyz/tap-salesforce-commerce) | | Target Repo | [https://gitlab.com/hotglue/target-salesforce-commerce](https://gitlab.com/hotglue/target-salesforce-commerce) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | | Unified Schema | Supported in [Ecommerce Unified Schema](https://hotglue.com/docs/unified). (Supported tables: Products, Orders, Customers) | # Salesforce Marketing Cloud Source: https://docs.hotglue.com/connectors/salesforce-marketing # Connector Details | Name | Value | | :- | :- | | Platform | [Salesforce Marketing Cloud](https://marketingcloudapis.com) | | Auth Type | API Keys | | Direction | Read | | Triggers | Supported (6 triggers available by default) | | Tap Repo | [https://github.com/hotgluexyz/tap-salesforce-marketing](https://github.com/hotgluexyz/tap-salesforce-marketing) | | Tap Metrics | Usage: (high) Success Rate: (high) | # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.7.11](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.11) | | > | [v1.7.10](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.10) | | > | [v1.7.9](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.9) | | > | [v1.7.8](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.8) | | > | [v1.7.7](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.7) | | > | [v1.7.6](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.6) | bug fixes | > | [v1.7.5](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.5) | fix catalog issue | > | [v1.7.4](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.4) | | > | [v1.7.3](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.3) | | > | [v1.7.2](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.2) | | > | [v1.7.1](https://github.com/hotgluexyz/tap-salesforce-marketing/releases/tag/v1.7.1) | | # Salesloft Source: https://docs.hotglue.com/connectors/salesloft # Connector Details | Name | Value | | :- | :- | | Platform | [Salesloft](https://salesloft.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-salesloft](https://gitlab.com/hotglue/tap-salesloft) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Unified Schema | Supported in [Sales Unified Schema](https://hotglue.com/docs/unified). (Supported tables: Activities, Contacts, Campaigns) | # Sellercloud Source: https://docs.hotglue.com/connectors/sellercloud # Connector Details | Name | Value | | :- | :- | | Platform | [Sellercloud](https://sellercloud.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-sellercloud](https://github.com/hotgluexyz/tap-sellercloud) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Sellsy Source: https://docs.hotglue.com/connectors/sellsy-v1 # Connector Details | Name | Value | | :- | :- | | Platform | [Sellsy](https://sellsy.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-sellsy-v1](https://gitlab.com/hotglue/tap-sellsy-v1) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Sendinblue Source: https://docs.hotglue.com/connectors/sendinblue # Connector Details | Name | Value | | :- | :- | | Platform | [Sendinblue](https://sendinblue.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-sendinblue](https://github.com/hotgluexyz/tap-sendinblue) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Sendinblue connector. The first thing you will need to do get your Sendinblue credentials is make an Sendinblue account. You can [make a free account (or sign up for a paid account) at this link](https://www.sendinblue.com/pricing/). If you already have an account, you can [log in at this link](https://app.sendinblue.com/account/login). ## API Key First, we are going to go through how to find your personal API key. ![](https://files.readme.io/71bcb70-Screen_Shot_2021-11-24_at_2.57.24_PM.png "Screen Shot 2021-11-24 at 2.57.24 PM.png") Once you have logged in to Sendinblue, you will be shown the home page of the Sendinblue platform. In the top right corner, Sendinblue has your company name. Go ahead and click it. ![](https://files.readme.io/4a91ae8-Screen_Shot_2021-11-24_at_2.57.24_PM.png "Screen Shot 2021-11-24 at 2.57.24 PM.png") Now go ahead and click on the **SMTP & API** tab from the drop down. ![](https://files.readme.io/ea2c0eb-Screen_Shot_2021-11-24_at_2.58.47_PM.png "Screen Shot 2021-11-24 at 2.58.47 PM.png") The next step is you should go ahead and click on the **Create A New API Key** button in the top right hand corner. ![](https://files.readme.io/441e678-Screen_Shot_2021-11-24_at_3.00.47_PM.png "Screen Shot 2021-11-24 at 3.00.47 PM.png") Next, go ahead and name your API Key **hotglue**. Once you have done that, click the **Generate** button. ![](https://files.readme.io/b5efe34-Screen_Shot_2021-11-24_at_3.08.44_PM.png "Screen Shot 2021-11-24 at 3.08.44 PM.png") Now you should be able to copy the API Key you've generated. Make sure you store this somewhere safe as you will not be able to access this key again. ![](https://files.readme.io/3056685-Screen_Shot_2021-11-24_at_3.09.38_PM.png "Screen Shot 2021-11-24 at 3.09.38 PM.png") You now have your API Key to put into hotglue! # SFTP Source: https://docs.hotglue.com/connectors/sftp # Connector Details | Name | Value | | :- | :- | | Platform | [SFTP](https://sftp) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-sftp](https://github.com/hotgluexyz/tap-sftp) | | Target Repo | [https://github.com/hotgluexyz/target-sftp](https://github.com/hotgluexyz/target-sftp) | | Tap Metrics | Usage: (high) | | Target Metrics | Usage: (medium) | # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v2.1.12](https://github.com/hotgluexyz/tap-sftp/releases/tag/v2.1.12) | | > | [v2.1.11](https://github.com/hotgluexyz/tap-sftp/releases/tag/v2.1.11) | | > | [v2.1.10](https://github.com/hotgluexyz/tap-sftp/releases/tag/v2.1.10) | | > | [v2.1.9 - Add option to remove file after sync](https://github.com/hotgluexyz/tap-sftp/releases/tag/v2.1.9) | - Added `delete_after_sync` option | > | [v2.1.8 - Improve performance and connection handling](https://github.com/hotgluexyz/tap-sftp/releases/tag/v2.1.8) | - Improve connection handling to keep open files \< 100 during execution | > | [v2.1.7 - Add parallel SFTP requests](https://github.com/hotgluexyz/tap-sftp/releases/tag/v2.1.7) | Use parallelization to improve SFTP tap runtime | > | [v2.1.6 - Fix TooManyFilesOpen error](https://github.com/hotgluexyz/tap-sftp/releases/tag/v2.1.6) | Fix TooManyFilesOpen error | > | [v2.1.5 - Silence paramiko error messages](https://github.com/hotgluexyz/tap-sftp/releases/tag/v2.1.5) | Update paramiko log level to CRITICAL | > | [v2.1.4 - Add retry logic](https://github.com/hotgluexyz/tap-sftp/releases/tag/v2.1.4) | - Added retry logic in case of server-side SSH protocol issues | > | [v2.1.3 - Automatically detect encoding](https://github.com/hotgluexyz/tap-sftp/releases/tag/v2.1.3) | Automatically detect encoding of CSV files rather than forcing all to `utf-8` | # Target Changelog > [accordion] Target Changelog > > | Version | Notes | > | :- | :- | > | [v1.0.1 - Allow relative paths](https://github.com/hotgluexyz/target-sftp/releases/tag/v1.0.1) | - Add support for relative paths | # SFTP Files Source: https://docs.hotglue.com/connectors/sftp-files # Connector Details | Name | Value | | :- | :- | | Platform | [SFTP Files](https://sftp) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-sftp-files](https://github.com/hotgluexyz/tap-sftp-files) | | Tap Metrics | Usage: (low) | # Credentials Setup Follow the steps below to get the credentials you need to use the SFTP Files connector. Configuring SFTP credentials is simple but requires an authentication method. A username and password or SSH key is required to set up the integration. The following credentials are required to connect to SFTP Files: * Username * Password * IP/Host name * Port # SharePoint Source: https://docs.hotglue.com/connectors/sharepoint # Connector Details | Name | Value | | :- | :- | | Platform | [SharePoint](https://sharepoint.microsoft.com) | | Auth Type | OAuth | | Direction | Read Only | | Tap Repo | [https://github.com/hotgluexyz/tap-sharepoint](https://github.com/hotgluexyz/tap-sharepoint) | # How to create a SharePoint OAuth App SharePoint OAuth applications are created and managed via Microsoft Entra ID The first thing that you need to do to get your Microsoft Business Central credentials is to register your OAuth app in Microsoft Entra: 1. [Sign in](https://entra.microsoft.com/) to the Microsoft Entra admin center as at least a Cloud Application Administrator. 2. Go to **Identity** > **Applications** > **App registrations** and select **New registration**. 3. Enter a display Name for your application. Users of your application might see the display name when they connect their SharePoint account. 4. For **Sign-in audience** make sure to allow all accounts to use your application 5. For **Redirect\_uri** use `https://hotglue.xyz/callback` 6. Complete your registration by pressing **Register** Make note of the automatically generated Application (client) ID, which you will need to configure your OAuth app in hotglue. The next step is to enable this OAuth app to access Microsoft SharePoint. On the left-hand panel, navigate to **Manage** > **API Permissions** Add the following permissions: * Microsoft Graph > `Sites.Read.All` * Microsoft Graph > `Files.Read.All` * Microsoft Graph > `User.Read` Finally, generate your Client secret by navigating to **Manage** > **Certificates and Secrets** > **Client Secrets** and add a new client secret. You'll need to add this secret key to hotglue in the next step. # How to enable the SharePoint Connector in hotglue To enable the SharePoint connector in hotglue, add the Sharepoint source to a new or existing flow, and add the `OAuth Client Id` and `OAuth Client Secret` under the source's credentials tab. # How tenants can find their SharePoint credentials The SharePoint connector requires tenants to enter three configuration options after linking their account: 1. subdomain (or `tenant_name`) This can be pulled from the URL your tenant uses to connect to their SharePoint site. For example, if their SharePoint url looks like `https://hotglueteam.sharepoint.com/sites/mysite`, then their tenant name is `hotglueteam`. 2. `site_name` The name of the SharePoint site they want to sync data from. 3. `drive_name` The drive of the SharePoint site they want to pull from After entering this information in the widget, your tenant will have the ability to select the relevant files and folders from their SharePoint drive: ![File Selection Demo](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/SharepointFileSelectionWidget.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=56e023a9f93b6da5a683547a471f5c86) # How tenants can link Sharepoint via the hotglue widget [Magic Link Feature Demo](https://www.loom.com/embed/30126c3281004594a3dd65eddff9631b?sid=6227c4ff-7532-44d8-ad26-40abaf4a9159) # ShipBob Source: https://docs.hotglue.com/connectors/shipbob # Connector Details | Name | Value | | :- | :- | | Platform | [ShipBob](https://shipbob.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-shipbob](https://github.com/hotgluexyz/tap-shipbob) | | Target Repo | [https://github.com/hotgluexyz/target-shipbob](https://github.com/hotgluexyz/target-shipbob) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # ShipHero Source: https://docs.hotglue.com/connectors/shiphero # Connector Details | Name | Value | | :- | :- | | Platform | [ShipHero](https://shiphero.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-shiphero](https://gitlab.com/hotglue/tap-shiphero) | | Tap Metrics | Usage: (low) Success Rate: (high) | # ShipStation Source: https://docs.hotglue.com/connectors/shipstation # Connector Details | Name | Value | | :- | :- | | Platform | [ShipStation](https://shipstation.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-shipstation](https://gitlab.com/hotglue/tap-shipstation) | | Tap Metrics | Usage: (low) Success Rate: (high) | | Unified Schema | Supported in [Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders, Products) | # Shopify Source: https://docs.hotglue.com/connectors/shopify # Connector Details | Name | Value | | :- | :- | | Platform | [Shopify](https://shopify.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Triggers | Supported (4 triggers available by default) | | Tap Repo | [https://github.com/hotgluexyz/tap-shopify](https://github.com/hotgluexyz/tap-shopify) | | Target Repo | [https://github.com/hotgluexyz/target-shopify-v2](https://github.com/hotgluexyz/target-shopify-v2) | | Tap Metrics | Usage: | | Target Metrics | Usage: | | Unified Schema | [Supported in Ecommerce Unified Schema.](https://hotglue.com/docs/unified) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| | Target Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Credentials Setup Follow the steps below to get the credentials you need to use the Shopify connector. There are two ways to use Shopify: either via a Shopify Public App (OAuth) or using a Private App (API keys). hotglue environments will default to private apps, but you can use either. Below are guides to setting up both: ## Public App (OAuth) > [!NOTE] > > When using Public App (OAuth), make sure to use the Shopify OAuth connector in hotglue instead of the API Key based version. ### 1. Register a Shopify Public App To start, you will need to create a Shopify developer account at [shopify.dev](https://shopify.dev/). After entering some basic information, you'll be taken to an overview page. There's a tab that says "Build apps for clients or the Shopify App Store." When you click it, you'll see a button to create an app. Click that too. Once you name your app, you'll get the Client ID and Client Secret that you need for hotglue. Add a logo and preferences URL while you're at it. ![Shopify Public App](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/ShopifyPublicApp.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=e830779f864072d538c056965854b46c) ### 2. App Setup There are two distinct ways to have hotglue manage your Shopify App. See the video walkthrough below explaining each option: [hotglue – Shopify OAuth apps](https://www.loom.com/embed/2a670c7b3fe942c6bf15a9e78ffe1e0f) In both scenarios, you must: 1. Add hotglue to the "Allowed redirection URL." This should be set to `https://hotglue.xyz/callback` ![Shopify Redirect URL](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/ShopifyRedirectUri.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=1a4992d05cfd974c146a9d8cf31327a2) 2. Configure a URL to redirect to once the authorization process is complete (`complete_url`). This is done in the JSON definition under Settings -> Connectors -> Sources -> Shopify OAuth. (Or, if using bi-directional flows, via Settings -> Connectors -> Shopify OAuth) ```json theme={null} { "tap": "shopify:oauth", "version": "oauth", "isForked": true, "label": "Shopify", "icon": "https://s3.amazonaws.com/cdn.hotglue.xyz/images/logos/shopify.svg", "domain": "shopify.com", // NOTE: You can also customize this list of scopes "tap_url": "https://{shop}.myshopify.com/admin/oauth/authorize?scope=read_customers,read_inventory,read_orders,read_products", // NOTE: This is the URL the tenant will be sent to once they complete the OAuth process "complete_url": "https://app.acme.com/" } ``` #### 2a. Fully Managed With this method, hotglue will handle generating the tenant ID + creating the config. To use this method, simply set your app URL to ``` https://api.hotglue.com/shopify/{env_id}/{flow_id} ``` #### 2b. Semi Managed Set a custom app URL (to your webapp for example), and then "forward" the request to hotglue. With this method you can supply the desired `tenant` id in the query params. Here's a simplified example using Express to illustrate how the semi-managed flow works: ```javascript theme={null} app.get('/app', async (req, res, next) => { // Get the query params const { shop } = req.query; // TODO: write some logic to decide what the tenant id should be const tenantId = "magic-ruffalo-123"; // Redirect the tenant to complete the Shopify OAuth process (notice we are forwarding the shop and tenant query params) const url = `${HG_API_URL}/shopify/${HG_ENV_ID}/${HG_FLOW_ID}?shop=${shop}&tenant=${tenantId}` console.log("Redirecting to: ", url); res.redirect(302, url); }); ``` ### 3. API Access Depending on your use case, you may need to request permissions for access to certain scopes. Most use cases will require the "Read all orders" scope, which you can request on this page. If it's relevant to your app, it isn't too hard to get this access. You may also be interested in requesting subscription APIs and protected customer data. ![Shopify API Access](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/ShopifyAPIAccess.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=928bf657677c14bd62ef684befb8feab) ### 4. Distribution Once you finish configuring your app and confirming that it works for your own account, you can begin the app registration process. You will want to make your app publicly available, so this can't be a Single Merchant Install. There is a one-time \$99 fee associated with registering to be on the Shopify app store. ![Shopify Distribution](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/connectors/images/ShopifyDistribution.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=e6b5955e9232ba5d7a9c29358eaf6767) ## Custom Apps (OAuth) If you are creating a one-off connection to one shop or a small number of shops, you can create an OAuth Custom App. The benefits of this approach are that: * You do not need to worry about unknown merchants installing your application. * You can avoid the drawn-out approval process that comes with public apps. The drawbacks are that: * Shopify does not allow you to use this approach as a full "workaround" for obtaining a public app. If you are connecting many tenants, Shopify expects you to build a public app. * You will need to manually generate the app for each user, then send the installation links to customers individually. ### Setup The process to create a custom app is very similar to creating a public app. All of the steps for Custom Apps are the same as those listed above for public apps, with the exceptions of: * `3a` / `3b` -> Instead of opting for Semi-Managed, you should always stick to Fully managed. Since you are creating the app for a specific customer, you can just add the tenant ID to your `App URL` that you configure in Shopify. This will look like the below: ``` https://api.hotglue.com/shopify/{env_id}/{flow_id}?tenant= ``` * `Distribution` -> Instead of creating a public app, you will create your app for a specific store. You will need to obtain the shop URL from your customer. Once you assign the app to that specific store, you will obtain an authorization link, which much be manually shared with the customer. With those two changes, the customer will click on the installation link and go through authorization like normal. The tenant will be linked in hotglue, with an access token, once they successfully complete the authorization workflow. ## Custom Apps (Client Credentials) > [!NOTE] > > Custom Apps are limited to a single store, which means these steps need to be performed for **each of your customers**. ### Register the app The first thing you need to do is log in to [Shopify](https://shopify.com). If you're just testing you can create a free partner account. Once logged in, on the left side of the screen, select the Apps option in the navigation bar. From there, select "Build apps in Dev Dashboard" ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyDevDashboard.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=19e623434dd785363639bce5304a1688) Once you're in the Shopify Dev Dashboard, create an app. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyCreateApp.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=8308262c4a2dc9bae4d09c9bf47421c1) We will create the app directly in the dashboard – give your app a name. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyAppName.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=278e2334c0c41ba3e23d390f30f112ab) ### Configure distribution Now we will set the app distribution settings. The easiest way to do this is to scroll down to the Access section, and click "Request access". This will redirect you to the Shopify Partner dashboard. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyRequestAccess.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=23383811564a727db3140d0af9141bcd) Select Distribution in the left side nav. Choose Custom distribution and "Select" to continue. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyCustomDistribution.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=adc573c847b94bfac896922835009810) This restricts your app to a single store. Input your store domain as requested. Click Generate Link. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyGenLink.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=31e5eb0f71d2891b9ed68453ae24ecd6) You can now use the resulting link to install the app. We will do this after we select permissions. For now, just note it. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyLinkInstall.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=dd7f158da25c3af997dd5b9f4a773885) ### Configure permissions Now you need to enable permissions. Head back to the Shopify Dev Dashboard and scroll down to the Access section, and click "Select scopes" ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyAppScopes.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=fbfc131c53a8de28bc549db8d2c1ec47) From the resulting menu, select the relevant scopes. > [!NOTE] > > If you plan to both read and write data with Shopify, make sure to enable **Read and write** access. Otherwise, **Read** access is sufficient. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifySelectScopes.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=14ff867768101049991dc9d321c44a30) Once you select the relevant scopes, click Done. You should see the selected scopes listed in the Access section. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyFinalScopes.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=b047e873327bc9c370ac7d156f78b944) ### Release We will now click Release to save our first version of the app. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyRelease.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=38392b0ab674b0e37362342ff894dc2f) You can leave the version name blank and confirm by clicking Release. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyConfirmRelease.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=711e083db3ee76ed2a5ba21bd1560a76) ### Install the app There are two ways to install this app. You can use the link we generated earlier, or directly in the Shopify Dev Dashboard you can click Home -> Install -> Select the store. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyInstallApp.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=2c1d2c856146abf2cf50a1a48d86fa05) Once you go through this flow, the user will be prompted to grant the requested permissions: ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyInstallConfirm.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=e4add35bf896671d2eea6d3a6f9e0d68) ### Get credentials Now that the app is installed on the store, you can use the **Client Id** and **Client Secret** pair in Hotglue! To view the **Client Id** and **Client Secret** of our new app click on Settings in the left side nav. ![](https://mintcdn.com/hotglue/HqxcKJnhGIPfz7dY/connectors/images/ShopifyClientCreds.png?fit=max\&auto=format\&n=HqxcKJnhGIPfz7dY\&q=85\&s=ab428fda446a4035a010006f2cf516d4) # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v1.4.13](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.13) | | > | [v1.4.12](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.12) | | > | | | > | [v1.4.10](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.10) | | > | [v1.4.9](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.9) | | > | [v1.4.8](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.8) | | > | [v1.4.7](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.7) | | > | [v1.4.6](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.6) | | > | [v1.4.5](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.5) | - Update retry logic | > | [v1.4.4](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.4) | - Add new streams - Optimize tap performance | > | [v1.4.3 - Add shop stream](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.3) | - Added `shop` stream | > | [v1.4.2 - Add support for incoming](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.2) | Added support for `incoming` orders | > | [v1.4.1 - Add support for access\_token](https://github.com/hotgluexyz/tap-shopify/releases/tag/v1.4.1) | Added support to use the key `access_token` in the config in addition to `api_key` | # SHOPLAZZA Source: https://docs.hotglue.com/connectors/shoplazza # Connector Details | Name | Value | | :- | :- | | Platform | [SHOPLAZZA](https://shoplazza.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-shoplazza](https://gitlab.com/hotglue/tap-shoplazza) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Shoptet Source: https://docs.hotglue.com/connectors/shoptet # Connector Details | Name | Value | | :- | :- | | Platform | [Shoptet](https://shoptet.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-shoptet](https://gitlab.com/hotglue/tap-shoptet) | | Tap Metrics | Usage: (medium) Success Rate: (high) | # SkuVault Source: https://docs.hotglue.com/connectors/skuvault # Connector Details | Name | Value | | :- | :- | | Platform | [SkuVault](https://skuvault.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-skuvault](https://gitlab.com/hotglue/tap-skuvault) | | Target Repo | [https://gitlab.com/hotglue/target-skuvault](https://gitlab.com/hotglue/target-skuvault) | | Tap Metrics | Usage: (low) Success Rate: (high) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Slack Source: https://docs.hotglue.com/connectors/slack # Connector Details | Name | Value | | :- | :- | | Platform | [Slack](https://slack.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-slack](https://github.com/hotgluexyz/tap-slack) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| # Credentials Setup Follow the steps below to get the credentials you need to use the Slack connector. The first thing that you need to do to get your Slack OAuth credentials is to head to the [Slack API dashboard](https://api.slack.com). If you do not have a Slack account, you will be prompted to create one. Once you're on the Slack API dashboard, select **create new app** ![](https://files.readme.io/a36cfc6-Screen_Shot_2022-01-27_at_3.03.52_PM.png) In the popup, select **Create from scratch** ![](https://files.readme.io/bbb711f-Screen_Shot_2022-01-27_at_3.04.44_PM.png) Now give your app a name, and pick a Slack workspace to test with, then click Create App ![](https://files.readme.io/cfbe60f-Screen_Shot_2022-01-27_at_3.06.55_PM.png) From the next screen, select OAuth & Permissions ![](https://files.readme.io/610782b-Screen_Shot_2022-01-27_at_3.07.28_PM.png) On the OAuth & Permissions page, scroll down to the **Redirect URLs** section, and add `https://hotglue.xyz/callback` as a valid URL and click **Save URLs** ![](https://files.readme.io/57cf0a7-Screen_Shot_2022-01-27_at_3.08.20_PM.png) Now scroll down to the **Scopes** section. For hotglue to work, you must grant the following scopes: * `channels:history` * `channels:join` * `channels:read` * `files:read` * `groups:read` * `links:read` * `reactions:read` * `remote_files:read` * `remote_files:write` * `team:read` * `usergroups:read` * `users.profile:read` * `users:read` * `users:read.email` ![](https://files.readme.io/3108aa5-Screen_Shot_2022-01-27_at_3.16.46_PM.png) Finally, click on Basic Information in the top left. ![](https://files.readme.io/c78ffbf-Screen_Shot_2022-01-27_at_3.17.48_PM.png) Now scroll down to the **App Credentials** section. Here you will be able to access the necessary client id and client secret. ![](https://files.readme.io/b00fbd7-Screen_Shot_2022-01-27_at_3.20.20_PM.png) You can now use these credentials in hotglue to configure your Slack integration! # Add your Slack bot to a channel Once a user has authenticated via OAuth with your Slack app, your bot will be available in the apps list of their Slack workspace. But before the bot can read any **messages**, you must first add them in the channels you wish to get messages from. Go to channel details in Slack and click on **Integrations** ![](https://files.readme.io/084fdd1-Screen_Shot_2022-01-27_at_4.08.44_PM.png) From here, click on **Add an App**, and select your app in the list ![](https://files.readme.io/b17d136-Screen_Shot_2022-01-27_at_4.09.24_PM.png) That's it! # Snowflake Source: https://docs.hotglue.com/connectors/snowflake # Connector Details | Name | Value | | :- | :- | | Platform | [Snowflake](https://snowflake.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-snowflake](https://github.com/hotgluexyz/tap-snowflake) | | Target Repo | [https://github.com/hotgluexyz/target-snowflake](https://github.com/hotgluexyz/target-snowflake) | | Tap Metrics | Usage: | | Target Metrics | Usage: | # Credentials Setup The snowflake connector uses the following 8 connection parameters: ```json theme={null} { "user": "my_user", "account": "rtxxxxx.eu-central-1", "warehouse": "my_virtual_warehouse", "dbname": "database_name", "default_target_schema": "my_target_schema" "private_key": "---BEGIN ENCRYPTED PRIVATE KEY----.....", "private_key_password": "..." "file_format": "snowflake_file_format_object_name", (Target only) } ``` Follow the steps below to find each of these in Snowflake. ### 1. `user` If you do not already have a Snowflake account, you can create one [here](https://www.snowflake.com/login/). ![](https://files.readme.io/5e77773-sign_in.png) This is the username that should be used when linking the Snowflake connector. ### 2. `account` Once signed in, you'll be taken to a homepage with a url that looks like: ``` https://app.snowflake.com///#/homepage ``` For the `account` field, users should enter "ORG\_ID-ACCOUNT\_ID". For example, if this is your url: ``` https://app.snowflake.com/rybaofs/ftb21143/#/homepage ``` Your `account` parameter should be set to `rybaofs-ftb21143`. ### 3. `warehouse` You can find a list of valid `warehouses` in `Admin` > `Warehouses` ![Snowflake Warehouse Name Pn](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/SnowflakeWarehouseName.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=2bed478a3029c122d09d871d3ee6b5a3) Use the name of your primary, active warehouse for the `warehouse` field. ### 4. `database`, and `schema` Navigate to `Data` > `Databases`, and click the **Add Database** button in the top right corner. ![](https://files.readme.io/d626ca4-database_01.png) You can now create the new database, noting the `name`: ![](https://files.readme.io/72a4109-create_db.png) Next, you should search for `Schema` in the secondary navigation bar. You will now be able to see your database name (this example is called Target Test). Within Target Test, you can see the available schemas for this database. Input the desired schema as the `schema` field in hotglue. ![](https://files.readme.io/57055da-schema_name.png) ![](https://files.readme.io/57055da-schema_name.png) ### 5. `file_format` Next, you need to create a named file format in your Snowflake schema. This will be used by the MERGE/COPY commands to parse the files correctly from S3. To use CSV files you can create a file format using the command: ``` CREATE FILE FORMAT {database}.{schema}.{file_format_name} TYPE = 'CSV' ESCAPE='\\' FIELD_OPTIONALLY_ENCLOSED_BY='"'; ``` You should use your chosen `file_format_name` as the `file_format` connection parameter. ### 6. Authenticating with key-pair authentication Finally, you can generate your private key by running the following command in your local terminal: ```bash theme={null} openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt ``` If you wish to use an encrypted key, you can instead run the command without the `-nocrypt` flag: ``` openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 des3 -inform PEM -out rsa_key.p8 ``` If you are using an encrypted key, enter your key's password into the `private_key_password` field. These commands will generate a private key in the PEM format: ``` -----BEGIN ENCRYPTED PRIVATE KEY----- MIIE6T... -----END ENCRYPTED PRIVATE KEY----- ``` You can copy and paste the entirety of that key directly into Hotglue for the `private_key` parameter. Next, generate a public key for your private key with: ```bash theme={null} openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub ``` Finally, execute the following command in Snowflake to associate your public key with your user profile: ```SQL theme={null} ALTER USER example_user SET RSA_PUBLIC_KEY='MIIBIjANBgkqh...'; ``` # Target Snowflake Target Snowflake creates Snowflake tables and uploads data for every stream passed to it by the ETL output. ## Example ETL Script ```python theme={null} import gluestick as gs import os # Define standard Hotglue directories ROOT_DIR = os.environ.get("ROOT_DIR", ".") INPUT_DIR = f"{ROOT_DIR}/sync-output" OUTPUT_DIR = f"{ROOT_DIR}/etl-output" # Read sync output input = gs.Reader() # Get tenant id tenant_id = os.environ.get('USER_ID', os.environ.get('TENANT', 'default')) # Iterate through the different streams in the sync output for key in eval(str(input)): input_df = input.get(key) """ Here we get the metadata for extracting the key properties, such as primary and replication keys. The database export targets will utilize these primary keys when upserting data. If you wish to hardcode your choice of primary keys, you can do so here. """ metadata = input.get_metadata(key) if metadata.get("key_properties"): # Use the key_properties (e.g. primary and replication keys) from the catalog key_properties = eval(metadata["key_properties"]) else: key_properties = [] # Include tenant_id as a field if desired input_df["tenant"] = tenant_id # Write this stream to the OUTPUT directory with the specified key_properties gs.to_singer(input_df, key, OUTPUT_DIR, keys=key_properties) ``` ## Available config flags | Property | Type | Required? | Description | | - | - | - | - | | batch\_size\_rows | Integer | | (Default: 100000) Maximum number of rows in each batch. At the end of each batch, the rows in the batch are loaded into Snowflake. | | batch\_wait\_limit\_seconds | Integer | | (Default: None) Maximum time to wait for batch to reach `batch_size_rows`. | | flush\_all\_streams | Boolean | | (Default: False) Flush and load every stream into Snowflake when one batch is full. Warning: This may trigger the COPY command to use files with low number of records, and may cause performance problems. | | parallelism | Integer | | (Default: 0) The number of threads used to flush tables. 0 will create a thread for each stream, up to parallelism\_max. -1 will create a thread for each CPU core. Any other positive number will create that number of threads, up to parallelism\_max. | | parallelism\_max | Integer | | (Default: 16) Max number of parallel threads to use when flushing tables. | | primary\_key\_required | Boolean | | (Default: True) Log based and Incremental replications on tables with no Primary Key cause duplicates when merging UPDATE events. When set to true, stop loading data if no Primary Key is defined. | # Square Source: https://docs.hotglue.com/connectors/square # Connector Details | Name | Value | | :- | :- | | Platform | [Square](https://squareup.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-square](https://gitlab.com/hotglue/tap-square) | | Target Repo | [https://gitlab.com/hotglue/target-square](https://gitlab.com/hotglue/target-square) | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (low) | # Credentials Setup Follow the steps below to get the credentials you need to use the Square connector. The first thing you need to do is log in to the [Square Developer](https://squareup.com/login?app=developer\&return_to=https://developer.squareup.com/apps) portal. ![](https://files.readme.io/8d7e0e1-suqare-login-01.png "suqare-login-01.png") Enter the credentials and click on **Sign in** button. ![](https://files.readme.io/a02c62c-square-add-app.png "square-add-app.png") To add your app click on the add button. ![](https://files.readme.io/b1ab948-suqare-app-add-01.png "suqare-app-add-01.png") Enter your application name and save the changes. ![](https://files.readme.io/b8622ac-suqare-login-03.png "suqare-login-03.png") You will land on the Credentials page. Click on **OAuth** from left nav pane. ![](https://files.readme.io/e5483ab-suqare-login-04.png "suqare-login-04.png") You should add the Redirect URI **[https://hotglue.xyz/callback](https://hotglue.xyz/callback)**. Once you do, you can also get your Client ID and Client Secret. Now you can go ahead and copy the credentials into hotglue. # Squarespace Source: https://docs.hotglue.com/connectors/squarespace # Connector Details | Name | Value | | :- | :- | | Platform | [Squarespace](https://squarespace.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-squarespace](https://github.com/hotgluexyz/tap-squarespace) | | Target Repo | [https://github.com/hotgluexyz/target-squarespace](https://github.com/hotgluexyz/target-squarespace) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | | Unified Schema | Supported in [Ecommerce Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders, Products) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| | Target Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Stamped Source: https://docs.hotglue.com/connectors/stamped # Connector Details | Name | Value | | :- | :- | | Platform | [Stamped](https://stamped.io) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-stamped](https://gitlab.com/hotglue/tap-stamped) | | Tap Metrics | Usage: (medium) Success Rate: (high) | # Statflo Source: https://docs.hotglue.com/connectors/statflo # Connector Details | Name | Value | | :- | :- | | Platform | [Statflo](https://statflo.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-statflo](https://github.com/hotgluexyz/tap-statflo) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Stella Connect Source: https://docs.hotglue.com/connectors/stella-connect # Connector Details | Name | Value | | :- | :- | | Platform | [Stella Connect](https://medallia.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-stella-connect](https://github.com/hotgluexyz/tap-stella-connect) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # StoreFeeder Source: https://docs.hotglue.com/connectors/storefeeder # Connector Details | Name | Value | | :- | :- | | Platform | [StoreFeeder](https://storefeeder.com/) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-storefeeder](https://gitlab.com/hotglue/tap-storefeeder) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Storyous Source: https://docs.hotglue.com/connectors/storyous # Connector Details | Name | Value | | :- | :- | | Platform | [Storyous](https://storyous.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-storyous](https://gitlab.com/hotglue/tap-storyous) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Stripe Source: https://docs.hotglue.com/connectors/stripe # Connector Details | Name | Value | | :- | :- | | Platform | [Stripe](https://stripe.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-stripe](https://github.com/hotgluexyz/tap-stripe) | | Tap Metrics | Usage: (high) | | Tap Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| # Credentials Setup Follow the steps below to obtain the credentials required to connect your Stripe account with Hotglue. Stripe uses **API Keys** for authentication. These keys allow Hotglue to securely access data from your Stripe account. The first step is to log in to your [Stripe Dashboard](https://dashboard.stripe.com/). Once logged in, navigate to the **Developers** section in the left sidebar and click on **API Keys**. ![](https://mintcdn.com/hotglue/ZAmq1PNng8sETWAa/connectors/images/Stripe_API.png?fit=max\&auto=format\&n=ZAmq1PNng8sETWAa\&q=85\&s=ec4dd91587709a45e6871c8299d15990) Stripe API Key On the API Keys page, you will see two types of keys: * **Publishable Key** * **Secret Key** Hotglue requires the **Secret Key** in order to read data from your Stripe account. > 📘 Tip > > Make sure you copy the **Secret Key** and not the Publishable Key. The Secret Key provides the permissions required to access Stripe data through the API. Click **Reveal test key** or **Reveal live key**, depending on the environment you want to connect. ![](https://mintcdn.com/hotglue/ZAmq1PNng8sETWAa/connectors/images/Stripe_Secret_key.png?fit=max\&auto=format\&n=ZAmq1PNng8sETWAa\&q=85\&s=01298bc152492d69ad70c39999b2e1f6) Secret key Example Secret Key ```text theme={null} Stripe Secret key = sk_live_mk_1OHpc********** Stripe Account ID = acct_1O****** ``` After providing the API key & Account ID, Hotglue will authenticate with Stripe and begin syncing the available data objects. ## Supported Data Objects The Stripe connector supports reading several commonly used Stripe resources including: * Customers * Charges * Payment Intents * Checkout Sessions * Promotion Codes * Subscriptions * Balance Transactions * Invoices These objects can be used to power analytics pipelines, financial reporting, and customer insights workflows. Using a standard Secret API Key from your Stripe dashboard is sufficient for most use cases. 📘 Tip For testing environments, you can safely use the Test Secret Key provided by Stripe. Tap Changelog \[accordion] Tap Changelog |Version|Notes| | :--- | :--- | |[v1.5.6](https://github.com/hotgluexyz/tap-stripe/releases/tag/v1.5.6)|| |[v1.5.5](https://github.com/hotgluexyz/tap-stripe/releases/tag/v1.5.5)|| |[v1.5.4](https://github.com/hotgluexyz/tap-stripe/releases/tag/v1.5.4)|| |[v1.5.3 - Add support for payment intents](https://github.com/hotgluexyz/tap-stripe/releases/tag/v1.5.3)|- Add support for `payment_intents`\ \- Add `metadata` field to `checkout_session` object| |[v1.5.2](https://github.com/hotgluexyz/tap-stripe/releases/tag/v1.5.2)|- Add support for `promotion_codes` and `checkout_sessions`| \`\`\` # SurveyMonkey Source: https://docs.hotglue.com/connectors/surveymonkey # Connector Details | Name | Value | | :- | :- | | Platform | [SurveyMonkey](https://surveymonkey.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-surveymonkey](https://gitlab.com/hotglue/tap-surveymonkey) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Credentials Setup Follow the steps below to get the credentials you need to use the SurveyMonkey connector. The first thing that you need to do to get your SurveyMonkey OAuth credentials is to [login](https://www.surveymonkey.com/user/sign-in/) in to SurveyMonkey. If you do not have a SurveyMonkey account, you can create a free one [here](https://www.surveymonkey.com/user/sign-up/). ![](https://files.readme.io/1d9c0de-Screen_Shot_2022-01-25_at_9.54.31_AM.png "Screen Shot 2022-01-25 at 9.54.31 AM.png") Now that you have logged into SurveyMonkey, your home page should look similar to this. You should scroll all the way to the bottom of the page. ![](https://files.readme.io/cc616b5-Screen_Shot_2022-01-25_at_9.55.06_AM.png "Screen Shot 2022-01-25 at 9.55.06 AM.png") At the bottom of the page, there is a small tab called **Developers**. Go ahead and click on that. ![](https://files.readme.io/93aba60-Screen_Shot_2022-01-25_at_9.56.23_AM.png "Screen Shot 2022-01-25 at 9.56.23 AM.png") Now, you will be on the SurveyMonkey developer home page. Look in the header and click on the My Apps tab. ![](https://files.readme.io/40d543e-Screen_Shot_2022-01-25_at_9.58.10_AM.png "Screen Shot 2022-01-25 at 9.58.10 AM.png") On the My Apps page, go ahead and click the **Add a New App** button. ![](https://files.readme.io/cba5cf3-Screen_Shot_2022-01-25_at_9.58.59_AM.png "Screen Shot 2022-01-25 at 9.58.59 AM.png") On this page, you should go ahead and name your app as **your** company name, not hotglue. Remember, this is the app your customers will be seeing when they are connecting their SurveyMonkey account to your platform. Once you are done configuring your app details, you can go ahead and click the **Create App** button. **If you are wondering whether to make your app public or not, the benefit of making your app public is that you will then have the opportunity to be listed on SurveyMonkey's App Directory.** ![](https://files.readme.io/cacb75e-Screen_Shot_2022-01-25_at_10.10.23_AM.png "Screen Shot 2022-01-25 at 10.10.23 AM.png") Now you have your OAuth Client ID and Secret! There are still a couple things you must do before your app is ready to use. Head to the Settings tab of your app. ![](https://files.readme.io/7639073-Screen_Shot_2022-01-25_at_10.12.29_AM.png "Screen Shot 2022-01-25 at 10.12.29 AM.png") You should now go ahead and replace the current OAuth Redirect URL with: ```html theme={null} https://hotglue.xyz/callback ``` Make sure to press submit changes once you've done that! ![](https://files.readme.io/f348a39-Screen_Shot_2022-01-25_at_10.14.39_AM.png "Screen Shot 2022-01-25 at 10.14.39 AM.png") Next, you need to scroll down to the scopes section of SurveyMonkey and enable these scopes for your app. **Important to note that if you change these scopes while you have users connected via this app, they will need to re-authenticate.** ![](https://files.readme.io/9f7625e-Screen_Shot_2022-01-25_at_10.17.38_AM.png "Screen Shot 2022-01-25 at 10.17.38 AM.png") And now you are ready to plug the credentials into hotglue! ## Survey ID ![](https://files.readme.io/ca1c33b-Screen_Shot_2022-01-25_at_10.45.32_AM.png "Screen Shot 2022-01-25 at 10.45.32 AM.png") Now to get your Survey ID, you need to head back to the main Survey Monkey Dashboard. In the main dashboard, you should go ahead and click on the My Surveys tab in the top left hand side of your screen. ![](https://files.readme.io/3024c4f-Screen_Shot_2022-01-25_at_10.48.50_AM.png "Screen Shot 2022-01-25 at 10.48.50 AM.png") On the Survey page, you are going to need to right click and Inspect the page (Inspect Element if you are on Windows). ![](https://files.readme.io/1632ce1-Screen_Shot_2022-01-25_at_10.49.57_AM.png "Screen Shot 2022-01-25 at 10.49.57 AM.png") Now you should be able to see the ID for that survey! Take that ID and plug it into hotglue. # Toast Source: https://docs.hotglue.com/connectors/toast # Connector Details | Name | Value | | :- | :- | | Platform | [Toast](https://toasttab.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/singer-io/tap-toast](https://github.com/singer-io/tap-toast) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Integration methods There are two supported ways to integrate with Toast: * using Toast APIs (there are restrictions here) * using SFTP exports ## Using APIs Toast has two types of API access: * integration partner access -> requires going through a lengthy partnership and approval process * standard API access -> only available on RMS Essentials plan or higher. Full requirements listed on the [Toast docs](https://doc.toasttab.com/doc/devguide/devApiAccessRequirements.html) > [!NOTE] > > Standard API access is read only and is only available on the RMS Essentials plan or higher. ### Configuration To generate standard API access credentials, you can follow the guide in the [Toast docs](https://doc.toasttab.com/doc/devguide/devApiAccessCredentials.html#devApiAccessCreatingCredentials). You will be given the following: * API access URL * Client Id * Client Secret ![API credentials](https://doc.toasttab.com/doc/media/dev-api-access-manage-credentials.png) After creating Standard API Credentials, the Restaurant GUID will be sent to your email. ![Restaurant GUID email](https://mintcdn.com/hotglue/QAKx8dwihOL9r98y/connectors/images/ToastRestaurantGUIDEmail.png?fit=max\&auto=format\&n=QAKx8dwihOL9r98y\&q=85\&s=8b567f770f952905d921fc45aabd3091) Additionally, you can request the Restaurant GUID via [Toast Support](https://support.toasttab.com/en/article/Locate-My-Restaurant-s-GUID). ### Supported data You can review Toast's [official Postman collection](https://doc.toasttab.com/doc/media/Toast_Postman_Collection.zip) to review what their APIs support. Our connector currently supports the following data: **supported tables** * Alternate Payment Types * Break Types * Cash Drawers * Cash Management Deposits * Cash Management Entries * Dining Options * Discounts * Employees * Menu Groups * Menu Items * Menu Option Groups * Menus * No Sale Reasons * Orders * Payments * Payout Reasons * Pre Modifier Groups * Pre Modifiers * Premodifier Groups * Premodifiers * Price Groups * Printers * Restaurant Services * Restaurants * Revenue Centers * Sales Categories * Service Areas * Tables * Tax Rates * Tip Withholding * Void Reasons ## SFTP exports Alternatively, Toast does offer the ability to create [data exports](https://doc.toasttab.com/doc/platformguide/adminDataExportOverview.html) and access them via SFTP. ### Configuration > [!NOTE] > > Configuring SFTP exports in Toast can be cumbersome on the user side. If possible to use the API approach (based on their subscription), that may be simpler. Generally, the steps are as follows: * The Toast user will need to request SFTP access from Toast (it is typically not enabled by default) * Once Toast provisions the SFTP connection, the user can configure the data exports they want. This is the most tedious part of the configuration. This is managed directly in the Toast UI under [Reports -> Settings -> Data Exports](https://doc.toasttab.com/doc/platformguide/configuringExports.html). * Configure the SFTP credentials in Hotglue From there, Toast will generate the files on a schedule and upload them to SFTP. From there, Hotglue will pick them up and process. ### Supported data Currently, our `toast-sftp` connector supports importing the following data from the data exports: **supported tables** | Stream Name | File Name | Format | Description | | - | - | - | - | | accounting\_report | `AccountingReport.xls` | Excel | Accounting data export with revenue amounts for each GL code | | all\_items\_report | `AllItemsReport.csv` | CSV | Information about all menu items | | cash\_entries | `CashEntries.csv` | CSV | Information about cash payments | | check\_details | `CheckDetails.csv` | CSV | Information about checks in orders | | house\_account\_export | `HouseAccountExport.csv` | CSV | Information about house accounts | | item\_selection\_details | `ItemSelectionDetails.csv` | CSV | Information about items ordered | | kitchen\_timings | `KitchenTimings.csv` | CSV | Information about kitchen tickets | | menu\_export | `MenuExport_*.json` | JSON | Information about menus | | menu\_export\_v2 | `MenuExportV2_*.json` | JSON | Enhanced information about menus | | menu\_menus | `MenuExport*.json` | JSON | Toast menu objects (flat, one per menu) | | menu\_groups | `MenuExport*.json` | JSON | Toast menu group objects with parent menu context | | menu\_items | `MenuExport*.json` | JSON | Toast menu item objects with full parent context | | menu\_option\_groups | `MenuExport*.json` | JSON | Toast menu option group objects with full parent context | | menu\_option\_items | `MenuExport*.json` | JSON | Toast menu option item objects with full parent context | | menu\_prices | `MenuExport*.json` | JSON | Toast menu item price objects with full parent context | | modifiers\_selection\_details | `ModifiersSelectionDetails.csv` | CSV | Information about modifiers applied to items | | order\_details | `OrderDetails.csv` | CSV | Information about orders | | payment\_details | `PaymentDetails.csv` | CSV | Information about payments | | time\_entries | `TimeEntries.csv` | CSV | Information about employee shifts | # Travefy Source: https://docs.hotglue.com/connectors/travefy # Connector Details | Name | Value | | :- | :- | | Platform | [Travefy](https://travefy.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-travefy](https://gitlab.com/hotglue/tap-travefy) | | Target Repo | [https://gitlab.com/hotglue/target-travefy](https://gitlab.com/hotglue/target-travefy) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | # Trustpilot Source: https://docs.hotglue.com/connectors/trustpilot # Connector Details | Name | Value | | :- | :- | | Platform | [Trustpilot](https://trustpilot.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/singer-io/tap-trustpilot](https://github.com/singer-io/tap-trustpilot) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Twilio Source: https://docs.hotglue.com/connectors/twilio # Connector Details | Name | Value | | :- | :- | | Platform | [Twilio](https://twilio.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/transferwise/pipelinewise-tap-twilio](https://github.com/transferwise/pipelinewise-tap-twilio) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [1.1.2 (2021-03-16)](https://github.com/transferwise/pipelinewise-tap-twilio/releases/tag/v1.1.2) | - Fix missing elements for streams without ordered response | > | [1.1.1 (2021-02-23)](https://github.com/transferwise/pipelinewise-tap-twilio/releases/tag/v1.1.1) | - Fix wrong JSON parsing of state.json | > | [1.1.0 (2021-02-22)](https://github.com/transferwise/pipelinewise-tap-twilio/releases/tag/v1.1.0) | - Transforms stringified JSONs to JSON objects - Enable streams to by synced since the last bookmark or start\_date with query parameter - Get more fields for events stream | > | [1.0.2 (2021-01-21)](https://github.com/transferwise/pipelinewise-tap-twilio/releases/tag/v1.0.2) | - Fix publishing to PyPI | > | [1.0.1 (2021-01-19)](https://github.com/transferwise/pipelinewise-tap-twilio/releases/tag/v1.0.1) | - Fix UsageRecords and UsageTriggers schemas - Fix pagination for Account subresources | > | [1.0.0 (2021-01-12)](https://github.com/transferwise/pipelinewise-tap-twilio/releases/tag/v1.0.0) | - Add programmable chat schemas and streams - Add taskrouter streams | # Twitter Source: https://docs.hotglue.com/connectors/twitter # Connector Details | Name | Value | | :- | :- | | Platform | [Twitter](https://twitter.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-twitter](https://gitlab.com/hotglue/tap-twitter) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Typeform Source: https://docs.hotglue.com/connectors/typeform # Connector Details | Name | Value | | :- | :- | | Platform | [Typeform](https://typeform.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-typeform](https://gitlab.com/hotglue/tap-typeform) | | Tap Metrics | Usage: (medium) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Typeform connector. ## Form ID The first thing you need to do is log in to [Typeform](https://admin.typeform.com/login). They have a free tier, so if you don't have an account, you can make one. ![](https://files.readme.io/8327aea-Screen_Shot_2022-01-25_at_3.50.43_PM.png "Screen Shot 2022-01-25 at 3.50.43 PM.png") If you do not currently have a Survey created, go ahead and create a mock Survey. Once you do, click on the three dots in the bottom right hand of the survey card. ![](https://files.readme.io/d3b060d-Screen_Shot_2022-01-25_at_3.57.13_PM.png "Screen Shot 2022-01-25 at 3.57.13 PM.png") Go ahead and click on the share tab from the resulting drop down. ![](https://files.readme.io/7347192-Screen_Shot_2022-01-25_at_3.59.48_PM.png) You can now find your Form ID after the last backslash in the share link. Go ahead and copy this into hotglue! ## Personal token ![](https://files.readme.io/6eeedcc-Screen_Shot_2022-01-25_at_4.08.52_PM.png "Screen Shot 2022-01-25 at 4.08.52 PM.png") Now that you've got your Form ID, it is time to get your Personal token. Go ahead and click the account icon in the top right corner, and then click on the accounting settings tab from the resulting dropdown. ![](https://files.readme.io/e990679-Screen_Shot_2022-01-25_at_4.13.16_PM.png "Screen Shot 2022-01-25 at 4.13.16 PM.png") On the settings page, navigate to the **Personal tokens** tab on the left hand side and click into it. ![](https://files.readme.io/7606bd0-Screen_Shot_2022-01-25_at_4.14.47_PM.png "Screen Shot 2022-01-25 at 4.14.47 PM.png") Now click on the **Generate a new token** button. ![](https://files.readme.io/9de6254-Screen_Shot_2022-01-25_at_4.15.27_PM.png "Screen Shot 2022-01-25 at 4.15.27 PM.png") Now go ahead and name your token (we suggest hotglue), and give it All scopes permission (this is the simplest and quickest way, though you can create custom scopes if you would like). ![](https://files.readme.io/5e23129-Screen_Shot_2022-01-25_at_4.17.42_PM.png "Screen Shot 2022-01-25 at 4.17.42 PM.png") You now have your token! Now you are only shown it once, so I would copy this into hotglue immediately and then store the token in a safe place. # Unanet Source: https://docs.hotglue.com/connectors/unanet # Connector Details | Name | Value | | :- | :- | | Platform | [Unanet](https://unanet.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-unanet](https://github.com/hotgluexyz/tap-unanet) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Unleashed Source: https://docs.hotglue.com/connectors/unleashed # Connector Details | Name | Value | | :- | :- | | Platform | [Unleashed](https://https://www.unleashedsoftware.com/) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-unleashed](https://gitlab.com/hotglue/tap-unleashed) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Vilkas Source: https://docs.hotglue.com/connectors/vilkas # Connector Details | Name | Value | | :- | :- | | Platform | [Vilkas](https://vilkasgroup.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-vilkas](https://gitlab.com/hotglue/tap-vilkas) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Wannafind Source: https://docs.hotglue.com/connectors/wannafind # Connector Details | Name | Value | | :- | :- | | Platform | [Wannafind](https://www.wannafind.dk) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-wannafind](https://gitlab.com/hotglue/tap-wannafind) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Wix Source: https://docs.hotglue.com/connectors/wix # Connector Details | Name | Value | | :- | :- | | Platform | [Wix](https://wix.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-wix](https://gitlab.com/hotglue/tap-wix) | | Target Repo | [https://gitlab.com/hotglue/target-wix](https://gitlab.com/hotglue/target-wix) | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (low) | | Unified Schema | Supported in [Ecommerce Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders) | # Credentials Setup Follow the steps below to get the credentials you need to use the Wix connector. Login to Wix from the [link](https://users.wix.com/signin). Enter you credentials on Login page. ![](https://files.readme.io/012fe76-image.png) You will land on Apps page. You can Create New App from this page. ![](https://files.readme.io/94ef4be-image.png) You will land on Dashboard page. You can change the name of your App. On this page you can find the documentation to set Up your App. ![](https://files.readme.io/4fdb579-image.png) From left navigation pane navigate to **Permissions**. You can Click on "**Add Permission**" button to add permission as per your requirements. ![](https://files.readme.io/3f14a38-image.png) Select the Permission Category and add the permission and save the settings from top right corner. ![](https://files.readme.io/1e01bd2-image.png) Navigate to OAuth from left navigation pane. Add Redirect URL and App URL. You can get App ID and Secret key from this page. Save the settings from **Save** button on top right corner. ![](https://files.readme.io/c70bc5d-image.png) Now Click on "Test Your App" option. From drop down Click on "**Create another development Site**" option. ![](https://files.readme.io/5653b5d-image.png) A pop-up will appear where you can select the site for your App. Click on **Save Site** after making the store selection. Now you can insert OAuth credentials into your hotglue Wix source settings and Connect to Wix. # WooCommerce Source: https://docs.hotglue.com/connectors/woocommerce # Connector Details | Name | Value | | :- | :- | | Platform | [WooCommerce](https://woocommerce.com) | | Auth Type | API Keys | | Direction | Bidirectional | | Triggers | Supported (8 triggers available by default) | | Tap Repo | [https://github.com/hotgluexyz/tap-woocommerce](https://github.com/hotgluexyz/tap-woocommerce) | | Target Repo | [https://github.com/hotgluexyz/target-woocommerce-v2](https://github.com/hotgluexyz/target-woocommerce-v2) | | Tap Metrics | Usage: (high) | | Target Metrics | Usage: (medium) | | Unified Schema | Supported in [Ecommerce Unified Schema](https://hotglue.com/docs/unified). (Supported tables: SalesOrders, Products, Customers, OrderNotes) | | Tap Capabilities |
  • Raises consistent hotglue exception classes for clearer job failures
| | Tap Supported Streams | | # Credentials Setup Follow the steps below to get the credentials you need to use the WooCommerce connector. Inside your WordPress admin view, head to your WooCommerce Settings > Advanced > REST API ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MiwKHeF18Im2tdbJ8iV%2F-MiwLoMPBVbxopowIKhZ%2FScreen%20Shot%202021-09-06%20at%202.25.00%20PM.png?alt=media\&token=56b9c3f5-06fd-48c5-9d6f-12a6b8cf28d6) WooCommerce REST API settings From here, select the Add key option to create a key for the integration. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MiwKHeF18Im2tdbJ8iV%2F-MiwMQ665zBdDXt12dj0%2Fimage.png?alt=media\&token=389e8a3d-1b98-4e91-af12-499efe5d1e40) ### Create a new REST API key Create your new consumer key pair, by writing a description, owner user, and permission level. For the WooCommerce source, you only need to provide Read level permissions. ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MiwKHeF18Im2tdbJ8iV%2F-MiwMf2m1Crqv7mzrepW%2FScreen%20Shot%202021-09-06%20at%202.28.45%20PM.png?alt=media\&token=5a4bbfc3-7f2f-4aac-a729-a8385ca635c2) ### Configure REST API consumer key pair Now you will have the consumer key pair you need! ![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MiwKHeF18Im2tdbJ8iV%2F-MiwN2EUHGQ1_5LWov7g%2Fimage.png?alt=media\&token=7289192f-6870-45be-a1b1-462a42d5ade4) Scroll down to the page and you will find API Secret. Now you can insert API Secret into your hotglue WooCommerce source settings. # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.42](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.42) | | > | [v0.0.41](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.41) | | > | [v0.0.40](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.40) | | > | [v0.0.39](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.39) | | > | [v0.0.38](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.38) | | > | [v0.0.37](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.37) | | > | [v0.0.36](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.36) | | > | [v0.0.35](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.35) | Add handling for missing rep key | > | [v0.0.34](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.34) | | > | [v0.0.33](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.33) | | > | [v0.0.32](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.32) | | > | [v0.0.31](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.31) | | > | [v0.0.30](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.30) | | > | [v0.0.29](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.29) | | > | [v0.0.28](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.28) | | > | [v0.0.27](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.27) | | > | [v0.0.26](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.26) | | > | [v0.0.25](https://github.com/hotgluexyz/tap-woocommerce/releases/tag/v0.0.25) | | # Target Changelog > [accordion] Target Changelog > > | Version | Notes | > | :- | :- | > | [v0.0.12](https://github.com/hotgluexyz/target-woocommerce-v2/releases/tag/v0.0.12) | | > | [v0.0.11](https://github.com/hotgluexyz/target-woocommerce-v2/releases/tag/v0.0.11) | | > | [v0.0.10](https://github.com/hotgluexyz/target-woocommerce-v2/releases/tag/v0.0.10) | | > | [v0.0.9](https://github.com/hotgluexyz/target-woocommerce-v2/releases/tag/v0.0.9) | | # Xero Source: https://docs.hotglue.com/connectors/xero # Connector Details | Name | Value | | :- | :- | | Platform | [Xero](https://xero.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-xero](https://github.com/hotgluexyz/tap-xero) | | Target Repo | [https://github.com/hotgluexyz/target-xero-v3](https://github.com/hotgluexyz/target-xero-v3) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (medium) | | Unified Schema | Supported in [Accounting Unified Schema](https://hotglue.com/docs/unified). (Supported tables: Accounts, Customers, Vendors, Items, Invoices, Classes, ProfitAndLossReport) | # Credentials Setup Follow the steps below to get the credentials you need to use the Xero connector. The first thing you need to do is log in to Xero, or create a free [Xero developer account](https://developer.xero.com/documentation/development-accounts/). ![](https://files.readme.io/c10e4a7-xero-add-02.png) Enter the credentials and click on **Log in** button. Navigate to [Xero Developer](https://developer.xero.com/app/manage) ![](https://files.readme.io/1f20bfd-app-create-01.png) You can create app by clicking "**New app**" button. A pop-out will appear. ![](https://files.readme.io/a17de82-create-app-02.png) Enter App name, integration type and fill mandatory fields. Click on the save buttton. Your app will be added. ![](https://files.readme.io/678171c-xero-add-03.png) Click on the name of the added app. ![](https://files.readme.io/ce4962c-xero-add-04.png) You will land on App details page. Click on Configuration from left nav pane. ![](https://files.readme.io/71d9bf6-xero-add-06.png) You should add the Redirect URI `https://hotglue.xyz/callback`. Once you do, you can also get your Client ID and generate Client Secret. Now you can go ahead and copy it into hotglue. Now you can insert the client id and client secret pair from the **Keys** section into your hotglue Xero source settings: ![](https://files.readme.io/a4821ac-sources-04.png) That's it! # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [v2.2.22](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.22) | | > | [v2.2.21](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.21) | | > | [v2.2.20](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.20) | | > | [v2.2.19](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.19) | | > | [v2.2.18](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.18) | | > | [v2.2.17](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.17) | | > | [v2.2.16](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.16) | | > | [v2.2.15](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.15) | | > | [v2.2.14](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.14) | | > | [v2.2.13](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.13) | | > | [v2.2.12](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.12) | | > | [v2.2.11](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.11) | | > | [v2.2.10](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.10) | fix issue with requirements | > | [v2.2.9](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.9) | fix replication | > | [v2.2.8](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.8) | add id to journal lines stream | > | [v2.2.7](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.7) | fixes | > | [v2.2.6](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.6) | add journal\_lines stream | > | [v2.2.5](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.5) | | > | [v2.2.4](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.4) | | > | [](https://github.com/hotgluexyz/tap-xero/releases/tag/v2.2.3) | | # Yotpo Source: https://docs.hotglue.com/connectors/yotpo # Connector Details | Name | Value | | :- | :- | | Platform | [Yotpo](https://yotpo.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://gitlab.com/hotglue/tap-yotpo](https://gitlab.com/hotglue/tap-yotpo) | | Tap Metrics | Usage: (medium) Success Rate: (high) | # Zendesk Source: https://docs.hotglue.com/connectors/zendesk # Connector Details | Name | Value | | :- | :- | | Platform | [Zendesk](https://zendesk.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Triggers | Supported (1 triggers available by default) | | Tap Repo | [https://github.com/hotgluexyz/tap-zendesk](https://github.com/hotgluexyz/tap-zendesk) | | Target Repo | [https://gitlab.com/hotglue/target-zendesk](https://gitlab.com/hotglue/target-zendesk) | | Tap Metrics | Usage: (low) Success Rate: (medium) | | Target Metrics | Usage: (low) Success Rate: (medium) | | Tap Capabilities |
  • Supports authenticating via hotglue's access token endpoint
  • Raises consistent hotglue exception classes for clearer job failures
| # Credentials Setup Follow the steps below to get the credentials you need to use the Zendesk connector. The first thing you need to do is log in to [Zendesk](https://zendesk.com). ![](https://files.readme.io/91725ca-zendesk-01.png "zendesk-01.png") Enter your organization's name and click on **Sign in** button. ![](https://files.readme.io/31a3c2e-Screenshot_1.png "Screenshot_1.png") You will land on the home page. Now you need to find OAuth Client ID and Client Secret. Click on **Settings** button. ![](https://files.readme.io/94c69f2-zendesk-03.png "zendesk-03.png") Click on "Go to Admin Center". ![](https://files.readme.io/823e237-Screenshot_2.png "Screenshot_2.png") You will land on the Admin home page. Select **Apps and Integrations** from left navigation pane. ![](https://files.readme.io/0e7a98a-zendesk-04.png "zendesk-04.png") Expand **Apps and Integrations** and Select **Zendesk API** from left pane. ![](https://files.readme.io/cfe8710-Screenshot_3.png "Screenshot_3.png") Navigate to OAuth Clients and click on the name of organization. ![](https://files.readme.io/45ed9bf-zendesk-05.png "zendesk-05.png") Scroll down the page and you can see OAuth Client ID and OAuth Client Secret. And here you have your Zendesk API Key! Go ahead and copy it into hotglue. # Zendesk Chat Source: https://docs.hotglue.com/connectors/zendesk-chat # Connector Details | Name | Value | | :- | :- | | Platform | [Zendesk Chat](https://zopim.com) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/singer-io/tap-zendesk-chat](https://github.com/singer-io/tap-zendesk-chat) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Zoho Source: https://docs.hotglue.com/connectors/zoho # Connector Details | Name | Value | | :- | :- | | Platform | [Zoho](https://zoho.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://gitlab.com/hotglue/tap-zoho](https://gitlab.com/hotglue/tap-zoho) | | Target Repo | [https://gitlab.com/hotglue/target-zoho](https://gitlab.com/hotglue/target-zoho) | | Tap Metrics | Usage: (low) | | Target Metrics | Usage: (low) | # Credentials Setup Follow the steps below to get the credentials you need to use the Zoho connector. The first thing that you need to do to get your Zoho OAuth credentials is to head to the [Zoho API Console](https://api-console.zoho.com/). Make sure that you go ahead and sign into Zoho in the top right hand corner. If you do not have a Zoho account, you will be prompted to create one. ![](https://files.readme.io/4737f5e-Screen_Shot_2022-04-04_at_12.19.42_PM.png "Screen Shot 2022-04-04 at 12.19.42 PM.png") Once you're on the Zoho API Console, select the **Get Started** button. ![](https://files.readme.io/dfe83b9-Screen_Shot_2022-04-04_at_12.24.29_PM.png "Screen Shot 2022-04-04 at 12.24.29 PM.png") On the Choose a Client Type page, you want to select the Server-based Applications option. ![](https://files.readme.io/5759d08-Screen_Shot_2022-04-04_at_12.34.01_PM.png "Screen Shot 2022-04-04 at 12.34.01 PM.png") Name the Client the name of your app, input your websites home page URL, and set the Authorized Redirect URIs to ` Once done, click the Create button. ![](https://files.readme.io/65508b9-Screen_Shot_2022-04-04_at_12.41.39_PM.png "Screen Shot 2022-04-04 at 12.41.39 PM.png") Now you have your Client ID and your Client Secret! Go ahead and copy these into hotglue. # Zoho Inventory Source: https://docs.hotglue.com/connectors/zoho-inventory # Connector Details | Name | Value | | :- | :- | | Platform | [Zoho Inventory](https://zoho.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-zoho-inventory](https://github.com/hotgluexyz/tap-zoho-inventory) | | Target Repo | [https://github.com/hotgluexyz/target-zoho-inventory](https://github.com/hotgluexyz/target-zoho-inventory) | | Tap Metrics | Usage: (medium) Success Rate: (high) | | Target Metrics | Usage: (medium) Success Rate: (high) | # Zoho Books Source: https://docs.hotglue.com/connectors/zohobooks # Connector Details | Name | Value | | :- | :- | | Platform | [Zoho Books](https://zoho.com) | | Auth Type | OAuth | | Direction | Bidirectional | | Tap Repo | [https://github.com/hotgluexyz/tap-zohobooks](https://github.com/hotgluexyz/tap-zohobooks) | | Target Repo | [https://github.com/hotgluexyz/target-zohobooks](https://github.com/hotgluexyz/target-zohobooks) | | Tap Metrics | Usage: (medium) | | Target Metrics | Usage: (medium) | # Credentials Setup **Step 1** #### Step 1: Go to the Zoho API Console Go to the [Zoho API Console https://api-console.zoho.com](https://api-console.zoho.com). **Step 2** #### Step 2: Create a new Application If you see the following screen, then click `Get Started`. Otherwise, continue. ![](https://mintcdn.com/hotglue/MXLpjTCRR2PmjJP6/connectors/images/ZohobooksGetStarted.png?fit=max\&auto=format\&n=MXLpjTCRR2PmjJP6\&q=85\&s=6d0e22d34ad69491449076c3d27c9fc9) If you see this screen, then click `Add Client`. Otherwise, continue. ![](https://mintcdn.com/hotglue/MXLpjTCRR2PmjJP6/connectors/images/ZohobooksAddClientNext.png?fit=max\&auto=format\&n=MXLpjTCRR2PmjJP6\&q=85\&s=7dba63b8161e0e6d935bfe263ed41ee0) Click on `Server-based Applications`. ![](https://mintcdn.com/hotglue/MXLpjTCRR2PmjJP6/connectors/images/ZohobooksSelectServer.png?fit=max\&auto=format\&n=MXLpjTCRR2PmjJP6\&q=85\&s=0ce0e18c1ffa96e433b492967c4b55bc) Fill out the fields in the following manner: * Client Name: The name your tenants will see when connecting. * Homepage URL: Your homepage URL. * Authorized Redirect URIs: `https://hotglue.xyz/callback`. Then, hit the create button. ![](https://mintcdn.com/hotglue/MXLpjTCRR2PmjJP6/connectors/images/ZohobooksCredentialsFields.png?fit=max\&auto=format\&n=MXLpjTCRR2PmjJP6\&q=85\&s=f0a3739353bc6a029df89d4df106ae96) **Step 3** #### Step 3: Set your credentials to work in all regions Click on your newly created Application in the API Console (see Step 1 if need be). Hit `Settings`. Check the box that says `Use the same OAuth credentials for all data centers`. ![](https://mintcdn.com/hotglue/MXLpjTCRR2PmjJP6/connectors/images/ZohobooksRegionAll.png?fit=max\&auto=format\&n=MXLpjTCRR2PmjJP6\&q=85\&s=53e9e91c766c20a91b1b7d7e5788ad87) Click `Ok`. ![](https://mintcdn.com/hotglue/MXLpjTCRR2PmjJP6/connectors/images/ZohobooksConfirmMultiDC.png?fit=max\&auto=format\&n=MXLpjTCRR2PmjJP6\&q=85\&s=113dd132c694d7f1a54bf1ecdc0561df) **Step 4** #### Step 4: Copy your credentials to Hotglue Click on your newly created Application in the API Console (see Step 1 if need be). Hit `Client Secret`. ![](https://mintcdn.com/hotglue/MXLpjTCRR2PmjJP6/connectors/images/ZohobooksCopyCredentials.png?fit=max\&auto=format\&n=MXLpjTCRR2PmjJP6\&q=85\&s=f9e1ced23069facaf355bb1aae87a088) Copy your credentials to Hotglue. Congratulations, you have set up an OAuth app for your tenants to connect to! # Zoom Source: https://docs.hotglue.com/connectors/zoom # Connector Details | Name | Value | | :- | :- | | Platform | [Zoom](https://zoom.us) | | Auth Type | OAuth | | Direction | Read | | Tap Repo | [https://github.com/hotgluexyz/tap-zoom](https://github.com/hotgluexyz/tap-zoom) | | Tap Metrics | Usage: (low) Success Rate: (high) | # Credentials Setup Follow the steps below to get the credentials you need to use the Zoom connector. The first thing that you need to do to get your Zoom OAuth credentials is to head to the [Zoom Marketplace](https://marketplace.zoom.us/). Make sure that you go ahead and sign into Zoom in the top right hand corner. If you do not have a Zoom account, you will be prompted to create one. ![](https://files.readme.io/4bac460-Screen_Shot_2022-02-11_at_4.29.56_PM.png "Screen Shot 2022-02-11 at 4.29.56 PM.png") Once you're on the Zoom Marketplace, select the **develop** dropdown in the top right hand corner. ![](https://files.readme.io/c69ecf2-Screen_Shot_2022-02-11_at_4.31.48_PM.png "Screen Shot 2022-02-11 at 4.31.48 PM.png") From the resulting drop down, select **Build App**. ![](https://files.readme.io/d8ea062-Screen_Shot_2022-02-11_at_4.34.07_PM.png "Screen Shot 2022-02-11 at 4.34.07 PM.png") From here, go ahead and select that you want to create an **OAuth** app. ![](https://files.readme.io/ffb6801-Screen_Shot_2022-02-11_at_4.35.02_PM.png "Screen Shot 2022-02-11 at 4.35.02 PM.png") On this page, you should go ahead and name your app the name of your company or tool that you will want users to be connecting their Zoom accounts to. It is important that you make your app type **Account-level app**. For the last toggle, if you want your app to be on the Zoom App Marketplace, leave the toggle on! Once done, click the Create button. ![](https://files.readme.io/97ab67c-Screen_Shot_2022-02-11_at_4.37.54_PM.png "Screen Shot 2022-02-11 at 4.37.54 PM.png") You will now be on this page. The next thing you need to do is put ```text theme={null} https://hotglue.xyz/callback ``` as the Redirect URL for OAuth under the development setting. ![](https://files.readme.io/446d527-Screen_Shot_2022-02-11_at_4.39.35_PM.png "Screen Shot 2022-02-11 at 4.39.35 PM.png") Then you will need to scroll down the page and input the same link in the Redirect URL for OAuth in Production, as well as the Add allow lists section. Once done, click Continue in the bottom right hand corner of your screen. ![](https://files.readme.io/29dd69f-Screen_Shot_2022-02-11_at_4.44.09_PM.png "Screen Shot 2022-02-11 at 4.44.09 PM.png") Now you should go ahead and fill out all your information here. ![](https://files.readme.io/c5f685c-Screen_Shot_2022-02-11_at_4.48.30_PM.png "Screen Shot 2022-02-11 at 4.48.30 PM.png") Once you fill out all your information, go ahead and click continue. ![](https://files.readme.io/1b542f7-Screen_Shot_2022-02-11_at_4.49.18_PM.png "Screen Shot 2022-02-11 at 4.49.18 PM.png") You will then be on this page which you can skip - click the Continue button. ![](https://files.readme.io/6563f28-Screen_Shot_2022-02-11_at_4.49.53_PM.png "Screen Shot 2022-02-11 at 4.49.53 PM.png") You are now on the scopes page, and your app configuration here is very important. To add scopes, you need to click the **Add Scopes button**. ![](https://files.readme.io/b56109d-Screen_Shot_2022-02-11_at_4.52.58_PM.png "Screen Shot 2022-02-11 at 4.52.58 PM.png") Now is when you are actually selecting the scopes of your app. You need to enable all the scopes listed below: | Scopes | | :- | | meeting:read:admin | | webinar:read:admin | | user:read:admin | | account:read:admin | | report:read:admin | ![](https://files.readme.io/5d34a28-Screen_Shot_2022-02-11_at_4.53.44_PM.png "Screen Shot 2022-02-11 at 4.53.44 PM.png") Once you have finished configuring the app, click the Done button. ![](https://files.readme.io/0ef4db0-Screen_Shot_2022-02-11_at_4.56.13_PM.png "Screen Shot 2022-02-11 at 4.56.13 PM.png") Now that you have added your scopes, you have to give descriptions for each scope. This is not a big deal, so you can put whatever you like. Once you are done giving descriptions, click Continue. ![](https://files.readme.io/f19d3d9-Screen_Shot_2022-02-11_at_4.54.42_PM.png "Screen Shot 2022-02-11 at 4.54.42 PM.png") You can skip this page by clicking the Continue button. Once you get past this page, you can go ahead and submit your app! # Zuora Source: https://docs.hotglue.com/connectors/zuora # Connector Details | Name | Value | | :- | :- | | Platform | [Zuora](https://zuora.com) | | Auth Type | API Keys | | Direction | Read | | Tap Repo | [https://github.com/transferwise/pipelinewise-tap-zuora](https://github.com/transferwise/pipelinewise-tap-zuora) | | Tap Metrics | Usage: (low) Success Rate: (medium) | # Tap Changelog > [accordion] Tap Changelog > > | Version | Notes | > | :- | :- | > | [1.0.0 (2020-04-17)](https://github.com/transferwise/pipelinewise-tap-zuora/releases/tag/v1.0.0) | \* Initial fork of ([https://github.com/singer-io/tap-zuora](https://github.com/singer-io/tap-zuora)) 1.1.12 \* Auto select every supported columns when discovering catalog | # Connector Builder Source: https://docs.hotglue.com/custom-connectors/connector-builder Learn how to create custom taps using the Connector Builder ## Getting Started The Connector Builder is a great way to build taps without writing any code! We highly recommend starting with the walkthrough below: [Connector Builder demo](https://www.loom.com/embed/a71d2c4c7c2f4af3b58047b2b719969b) ### Open the builder To open the Connector Builder, head to your Environment Settings -> Connectors -> Build a Connector, as shown below: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/build-connector.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=1f0bc4db35abcfca1b57367d3bf346a2) From there, click Create New to start building a new tap. ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/create-new.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=54eb9773707391abd9267715fd86f320) ### Define basic details Now we can define our connector's basic details: * **Name**: this is the name that will appear when a tenant goes to connect the connector * **Tap ID**: this is the ID of the connector, will be used in API calls. It should be all lowercase, and hyphenated. For example, `sage-intacct` or `chargebee` * **Domain**: the domain of the product (`intacct.com`). This is only used to load a default logo * **Logo**: logo for the connector. Will be shown in the hotglue admin panel and in widget. ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/details.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=8c961d5918c18eb1dc50d2b96a1f7104) ## Authentication ### API Base URL The first step of configuring authentication is to define the base API URL. This can include variables. For example, for Shopify we could define the following, where `store_name` is a parameter the tenant will configure: ``` https://{config.store_name}.myshopify.com/admin/api/2025-04 ``` In most cases, the base URL is a static string, such as: ``` https://api.aircall.io/v1 ``` ### Authentication Method The Connector Builder currently supports the following authentication methods: * API Key * Basic * OAuth * Bearer ![](https://mintcdn.com/hotglue/FeAXmEmCIk4FzQKa/custom-connectors/images/oauth-dropdown.png?fit=max\&auto=format\&n=FeAXmEmCIk4FzQKa\&q=85\&s=bc4cd791d7b046f7b09f5287f13ddcc7) #### API Key For API Key based authentication, you need to specify the following: * **Location**: where should the API Key be injected in the request? Options are **Header** or **Query** * **Name**: what is the name of the **Header** or **Query** paramter? * **Value**: this is the API Key value. In most cases you should just point this to the config: `{config.api_key}` For example, if I wanted to include my API Key in the `x-api-key` header, I'd define the following: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/api-key-header.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=f00b5709672bed2c66edb9d9ae693fc3) Or, if I wanted to include my API Key in the `api_key` query parameter (meaning the request will have `?api_key={api_key}` in the URL), I'd define: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/api-key-query.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=6d24724d872f4365cf40303a23cff7f2) #### Basic For Basic authentication, you need to define the **Username** and **Password**. Following standard Basic auth convention, these will be concatenated with a colon `username:password` and then base64 encoded. In many cases, **Password** will be an empty string, in which case you can leave Password blank. See example below: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/authentication.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=26e4e3d1ac0b2a72984b26f685ac9395) #### OAuth For OAuth authentication, select **OAuth** from the Authentication Method dropdown: This reveals the following fields: ![](https://mintcdn.com/hotglue/FeAXmEmCIk4FzQKa/custom-connectors/images/oauth-settings.png?fit=max\&auto=format\&n=FeAXmEmCIk4FzQKa\&q=85\&s=5c0333d25e6dd85843cfbfdea0309e3b) * **Authorization URL**: The URL tenants are redirected to in order to grant access. This maps to `tap_url` in the connector definition. Hotglue automatically appends `client_id`, `state`, and `redirect_uri` — do not include them manually. * **Token URL**: The endpoint Hotglue calls to exchange the authorization code for an access token. This maps to `auth_url` in the connector definition. * **No Refresh Token**: Enable if the provider does not issue a refresh token (the access token is long-lived or must be re-authorized manually). * **Use PKCE Verifier**: Enable to add a PKCE `code_verifier` to the token exchange request. * **Use Basic Auth**: Enable to send `client_id` and `client_secret` as an HTTP Basic Auth header on the token request. When enabled, set `Include Client Credentials in Body` to off if the provider rejects credentials in the request body (see below). * **Use JSON Payload**: Enable to send the token request body as JSON instead of the default form-encoded format. **Request Payload** The Request Payload section shows the fields sent in the token refresh request body: ![](https://mintcdn.com/hotglue/FeAXmEmCIk4FzQKa/custom-connectors/images/oauth-request-payload.png?fit=max\&auto=format\&n=FeAXmEmCIk4FzQKa\&q=85\&s=5525f49d819c4cba1e2322887a7e3499) By default, this payload is automatically populated with `client_id`, `client_secret`, `redirect_uri`, `refresh_token`, and `grant_type` from the tenant's config. You can override these defaults by setting `authentication.refresh_request_body` in your tap definition. ## Parameters In the parameters section, you can define the fields tenants will need to fill in when they link this connector. Any of the parameters you define can be used in other sections (such as the Authentication step) by using the variable syntax. Such as: ``` {config.api_token} ``` For example, if I define the following: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/parameters.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=86d236c402c8de1064d75a1e9b7a3ce8) then in the widget tenants will see: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/widget-preview.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=806cbd8cb014da86ee52e68091787e2b) ## Streams The final thing to configure are the **Streams**. This is where you define the objects or tables this connector supports. For my example (Aircall), the stream I'll be configuring is `Calls`. ### Details To start, we'll define the following: * **Stream Name**: the name of the stream, this is only shown in the connector builder. For example, `Calls` * **Stream Id**: the id of the stream, this will be used in the field map and catalog. We recommend this being snakecase, e.g. `calls` * **URL Path**: the API endpoint to use, *without* the base URL. e.g. `/calls` * **Primary Key**: the field to use as the primary key. If there is no primary key, leave it empty. e.g. `id` * **HTTP Method**: either `GET` or `POST`. In almost all cases this will be `GET` * **Response Format**: the MIME type of the API response. In almost all cases this should be `application/json` ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/stream-details.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=e4e17cb96d923cbb5125b159d7fdba1a) ### Request #### Query Parameters In the query parameters section, you can specify fields that should be added to the request URL. This is commonly used for filtering data. For example, you may need to add a query parameter like `?status=Paid`. This can even reference config parameters if this behavior is configurable by users: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/request-parameters.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=a47e7bce84f6e9786da4e551cac1d5df) #### Pagination In the pagination section we define how to page through the API. We support two methods: **Page Increment** Page increment should be used if the API expects some sort of page parameter in the requests, typically in the URL. To use this, you specify the following: * **Location**: whether this should be a request parameter (in the URL) or in the headers * **Attribute**: the name of the field to use (e.g. `page`) * **Start From**: the first page (e.g. `1`) In the example below we are defining a `page` URL parameter, so requests will start from `?page=1` and continue until there is no more data. ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/pagination-page.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=f98697be3911868ff142fd2dcb083a7c) **Offset** With offset pagination, we expect the API to specify some parameter which we can use to get the next page of data. To use this, you specify the following: * **Location**: whether this should be a request parameter (in the URL) or in the headers * **Offset Parameter**: the name of the field to use to specify the offset (e.g. `offset`) * **Next Offset JSON Selector**: the JSON Path to where in the response the next offset will be (e.g. `next_offset`) * **Limit Parameter**: the name of the field to use to specify the limit (e.g. `limit`) * **Limit**: the number of records each page will have (e.g. `100`) The below example implements a typical offset setup (it's actually the format Chargebee's API uses!) ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/pagination-offset.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=e1b5b05d6908a6453d7b6aa0bca128e3) #### Incremental Sync This section is optional, and is used to specify a **replication key** (a datetime field) that can be used as a filte rin the API request, so we only sync new or updated data since the last job. To use this you will specify: * **Location**: whether this should be a request parameter (in the URL) or in the headers * **Replication Key**: the field in the response data we should use to filter (e.g. `updated_at`) * **Parameter Name**: the filter parameter in the API (e.g. `updated_at[after]`) * **Date Format**: the format the date will be in. Can be either `timestamp` for UNIX timestamps, or a standard date format like `%Y-%m-%d %H:%M:%S` Here's an example for Aircall, which has a `started_at` timestamp in the response data, and expects a filter in the URL like: `&from=` ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/incremental-sync.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=9d8c686d6c1e6913c94196fed0395353) ### Response #### JSON Selector First we specify the JSON path to the records within the response. For example, if I have a response payload that looks like: ```json theme={null} { "meta": { "count": 20, "total": 2234, "current_page": 1, "per_page": 20, "next_page_link": "https://api.aircall.io/v1/calls?order=asc&page=2&per_page=20", "previous_page_link": null }, "calls": [ { "id": 812, "sid": "CA1234567890", "direct_link": "https://api.aircall.io/v1/calls/812", "direction": "outbound", "status": "done", "started_at": 1584998199, "answered_at": 1584998205, "ended_at": 1584998210 }, { "id": 813, "direct_link": "https://api.aircall.io/v1/calls/813", "direction": "inbound", "status": "done", "started_at": 1584998199, "answered_at": "no_available_agent", "ended_at": 1584998210 } ] } ``` Then my JSON selector should be: ``` $.calls[*] ``` #### JSON Schema Finally, we specify the JSON Schema of the records. You can do this using the infer schema tool within hotglue, or manually in JSON. ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/infer-schema-tool.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=7815d930c512e6f40dc2ee1cfc83e001) To use the infer schema tool, you can simply paste a sample JSON record and click infer: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/infer-schema.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=174ef04a7a34b7066608fffcc0414264) This generates the JSON Schema automatically, which you can then modify as needed. For example, I modified the `started_at` field in my schema to be formatted as a `date-time` beause I am using it as the **Replication Key**: > [accordion] Sample JSON Schema > > ```json theme={null} > { > "type": "object", > "properties": { > "id": { > "type": [ > "integer", > "null" > ] > }, > "sid": { > "type": [ > "string", > "null" > ] > }, > "direct_link": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "direction": { > "type": [ > "string", > "null" > ] > }, > "status": { > "type": [ > "string", > "null" > ] > }, > "missed_call_reason": { > "type": [ > "null", > "null" > ] > }, > "started_at": { > "type": [ > "string", > "null" > ], > "format": "date-time" > }, > "answered_at": { > "type": [ > "string", > "null" > ], > "format": "date-time" > }, > "ended_at": { > "type": [ > "string", > "null" > ], > "format": "date-time" > }, > "duration": { > "type": [ > "integer", > "null" > ] > }, > "voicemail": { > "type": [ > "null", > "null" > ] > }, > "recording": { > "type": [ > "null", > "null" > ] > }, > "asset": { > "type": [ > "null", > "null" > ] > }, > "raw_digits": { > "type": [ > "string", > "null" > ] > }, > "user": { > "type": [ > "object", > "null" > ], > "properties": { > "id": { > "type": [ > "integer", > "null" > ] > }, > "direct_link": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "name": { > "type": [ > "string", > "null" > ] > }, > "email": { > "type": [ > "string", > "null" > ], > "format": "email" > }, > "available": { > "type": [ > "boolean", > "null" > ] > }, > "availability_status": { > "type": [ > "string", > "null" > ] > }, > "created_at": { > "type": [ > "string", > "null" > ], > "format": "date-time" > }, > "time_zone": { > "type": [ > "string", > "null" > ] > }, > "language": { > "type": [ > "string", > "null" > ] > }, > "state": { > "type": [ > "string", > "null" > ] > }, > "wrap_up_time": { > "type": [ > "integer", > "null" > ] > } > } > }, > "contact": { > "type": [ > "null", > "null" > ] > }, > "archived": { > "type": [ > "boolean", > "null" > ] > }, > "assigned_to": { > "type": [ > "object", > "null" > ], > "properties": { > "id": { > "type": [ > "integer", > "null" > ] > }, > "direct_link": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "name": { > "type": [ > "string", > "null" > ] > }, > "email": { > "type": [ > "string", > "null" > ], > "format": "email" > }, > "available": { > "type": [ > "boolean", > "null" > ] > }, > "availability_status": { > "type": [ > "string", > "null" > ] > }, > "created_at": { > "type": [ > "string", > "null" > ], > "format": "date-time" > }, > "time_zone": { > "type": [ > "string", > "null" > ] > }, > "language": { > "type": [ > "string", > "null" > ] > }, > "state": { > "type": [ > "string", > "null" > ] > }, > "wrap_up_time": { > "type": [ > "integer", > "null" > ] > } > } > }, > "tags": { > "type": [ > "array", > "null" > ], > "items": { > "type": [ > "object", > "string", > "null" > ] > } > }, > "transferred_by": { > "type": [ > "null", > "null" > ] > }, > "transferred_to": { > "type": [ > "null", > "null" > ] > }, > "teams": { > "type": [ > "array", > "null" > ], > "items": { > "type": [ > "object", > "string", > "null" > ] > } > }, > "number": { > "type": [ > "object", > "null" > ], > "properties": { > "id": { > "type": [ > "integer", > "null" > ] > }, > "direct_link": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "name": { > "type": [ > "string", > "null" > ] > }, > "digits": { > "type": [ > "string", > "null" > ] > }, > "country": { > "type": [ > "string", > "null" > ] > }, > "time_zone": { > "type": [ > "string", > "null" > ] > }, > "open": { > "type": [ > "boolean", > "null" > ] > }, > "availability_status": { > "type": [ > "string", > "null" > ] > }, > "is_ivr": { > "type": [ > "boolean", > "null" > ] > }, > "live_recording_activated": { > "type": [ > "boolean", > "null" > ] > }, > "priority": { > "type": [ > "null", > "null" > ] > }, > "messages": { > "type": [ > "object", > "null" > ], > "properties": { > "welcome": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "waiting": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "ivr": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "voicemail": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "closed": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "callback_later": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "unanswered_call": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "after_hours": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "ringing_tone": { > "type": [ > "string", > "null" > ], > "format": "uri" > } > } > }, > "created_at": { > "type": [ > "string", > "null" > ], > "format": "date-time" > } > } > }, > "comments": { > "type": [ > "array", > "null" > ], > "items": { > "type": "object", > "properties": { > "id": { > "type": [ > "integer", > "null" > ] > }, > "content": { > "type": [ > "string", > "null" > ] > }, > "posted_by": { > "type": [ > "object", > "null" > ], > "properties": { > "id": { > "type": [ > "integer", > "null" > ] > }, > "direct_link": { > "type": [ > "string", > "null" > ], > "format": "uri" > }, > "name": { > "type": [ > "string", > "null" > ] > }, > "email": { > "type": [ > "string", > "null" > ], > "format": "email" > }, > "available": { > "type": [ > "boolean", > "null" > ] > }, > "availability_status": { > "type": [ > "string", > "null" > ] > }, > "created_at": { > "type": [ > "string", > "null" > ], > "format": "date-time" > }, > "time_zone": { > "type": [ > "string", > "null" > ] > }, > "language": { > "type": [ > "string", > "null" > ] > }, > "state": { > "type": [ > "string", > "null" > ] > }, > "wrap_up_time": { > "type": [ > "integer", > "null" > ] > } > } > }, > "posted_at": { > "type": [ > "integer", > "null" > ] > } > } > } > }, > "cost": { > "type": [ > "string", > "null" > ] > }, > "country_code_a2": { > "type": [ > "string", > "null" > ] > }, > "pricing_type": { > "type": [ > "string", > "null" > ] > }, > "recording_short_url": { > "type": [ > "null", > "null" > ] > }, > "voicemail_short_url": { > "type": [ > "null", > "null" > ] > } > } > } > ``` That's it! You've now configured a custom tap. From here you can add more streams, or click **Publish** to start adding it to flows and running jobs. ## Advanced Features ### Parent-Child Streams In some cases streams are nested and require a parent-child relationship to work properly. For example, if you have the following streams: * Clients `/clients` * Medical Forms `/clients/{client_id}/medical-forms` you will need to fetch the medical forms *for each* client. This is a great use case for parent-child streams. In the parent stream, we need to define the `child_context` – essentially a list of parameters the child streams will have access to in order to make their requests. ```json theme={null} "child_context": [ { "name": "client_id", "value": "$.details.id" } ] ``` In the child stream, we simply need to define the `parent_stream`: ```json theme={null} "parent_stream": "clients" ``` Watch the video below for a full walkthrough and demo of using parent-child streams: [Connector Builder demo](https://www.loom.com/embed/b2f8155f629443f4bca2d8c28036fe68) # Creating Singer taps Source: https://docs.hotglue.com/custom-connectors/creating-singer-taps Scaffold a tap with the Hotglue Cookiecutter starter and HotglueSingerSDK # Overview You can scaffold a new Singer tap from our public starter **[cookiecutter template](https://github.com/hotgluexyz/hotglue-tap-cookiecutter)**. The cookiecutter template: * uses **[HotglueSingerSDK](https://pypi.org/project/hotglue-singer-sdk/)** * includes **`AGENTS.md`** tailored to how we recommend building taps * linting with ruff (including a **GitHub Actions** `lint.yml` workflow), * support for `--access-token` / Hotglue **access token endpoint** behavior when you choose OAuth * a **VS Code launch** config for debugging. # Scaffold To scaffold your tap with the cookiecutter template run: ```bash theme={null} pip install cookiecutter cookiecutter https://github.com/hotgluexyz/hotglue-tap-cookiecutter.git cd pip install -e . ``` Follow the README in the generated repo for prompts and project-specific details. For local discover, stream selection, and sync, see [Running taps](/custom-connectors/taps). # Running Targets Source: https://docs.hotglue.com/custom-connectors/running-targets Learn how to run targets using the Singer SDK # Background A target is an integration that reads data and writes it to some *target* system. For example, hotglue supports targets for: * Uploading files to storage systems S3, Azure Blob Storage, or SFTP servers. * Creating and Updating invoices in ERPs like Netsuite, Sage Intacct, and Dynamics BC * Upserting records into databases like Postgres, Snowflake, and BigQuery In most cases, targets expect their input in the form of a [**Singer**](https://www.singer.io/) file, a variation of jsonl for structured streaming data. # Setting up a local target environment ## Virtual Environments Dependencies can differ from target to target, so it is best to use a virtual environment to isolate the target's Python dependencies. You can create a virtual environment named `.venv` in your target workspace with: ```bash theme={null} python -m venv .venv ``` You can then enter the virtual environment with: ```bash theme={null} source .venv/bin/activate ``` Finally, you can install the tap's dependencies depending on how they are specified: | Dependency File | Command | | :-: | :-: | | `requirements.txt` | `pip install -r requirements.txt` | | `setup.py` | `pip install -e .` | | `pyproject.toml` | `pip install -e .` | ## Config Targets require a valid config, which will include fields like API keys, OAuth credentials, and configuration flags. For example: ```json theme={null} { "client_id": "...", "client_secret": "...", "refresh_token": "...", "access_token": "...", "start_date": "2025-01-25T00:00:00Z" } ``` Most target will include information about the required config values in their README's. > 💡 To keep your workspace clean, create a `.secrets` folder to store your `config.json`. Run all tap commands out of this folder to make sure your catalogs and output data stay separate from relevant code. ## Using the Hotglue Access Token Endpoint For OAuth connectors, you can have the target use the [access token endpoint](https://docs.hotglue.com/api-reference/access-tokens/retrieve-access-token) instead of refreshing the token locally by: **1. Adding this flag to your `config.json`:** ```json theme={null} { "_refresh_token_via_hg_api": true, ... } ``` **2. Setting the following environment variables:** | Variable | Description | | :-: | :- | | `TENANT` | Your tenant ID | | `API_KEY` | Your Hotglue API key | | `FLOW` | The flow ID | | `ENV_ID` | The environment ID | | `TARGET` | The target ID (e.g. `salesforce`) | ```bash theme={null} export TENANT="" export API_KEY="" export FLOW="" export ENV_ID="" export TARGET="" ``` ## Data If you want to try to reproduce the behavior of a particular [hotglue job](/key-concepts/jobs/sync-jobs), you can download the job folder on your hotglue job page: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/DownloadJobImg.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=d34e7a2e14d2d6f8fe21646164825b99) The etl-output folder will contain the raw input file(s) used by the target. In most cases, you'll see a singular `data.singer` file with all your data: ```jsonl theme={null} {"type":"SCHEMA","stream":"Invoices","schema":{"type":["object","null"],"properties":{"invoiceId":{"type":["string","null"]},"date":{"type":["string","null"]},"total":{"type":["number","null"]}}},"key_properties":[]} {"type":"RECORD","stream":"Invoices","record":{"invoiceId":"INV-001","date":"2025-02-11T00:00:00.000Z","total":112.40}} {"type":"SCHEMA","stream":"InvoicePayments","schema":{"type":["object","null"],"properties":{"paymentId":{"type":["string","null"]},"amount":{"type":["number","null"]}}},"key_properties":[]} {"type":"RECORD","stream":"InvoicePayments","record":{"paymentId":"PAY-001","amount":85.50}} ``` Place your `data.singer` somewhere accessible by your target. We recommend placing it in a git-ignored `.secrets` with your `config.json` to avoid accidently committing it. # Running a target You can now pipe your data into the target. If your target is named `target-salesforce`, you would run: ``` target-salesforce < data.singer --config config.json > target-state.json ``` This will process your singer file line by line and (if supported by the target) write the export results to a file named `target-state.json`. If you attempted to send two contacts to Salesforce, your target state might look something like this: ```json theme={null} { "bookmarks": { "Contacts": [ { "hash": "372f2b3f76de48b1823db1ed2333042ef312ce2ba2b50165467ae64a78c05a71", "success": true, "id": 900, "externalId": "903093" } { "hash": "97a8sdhge48b1823db1ed2333042ef312ce2ba2b5016sd5467ae64a78c05a71", "externalId": "903094", "error": "Email 'Bi@ll@hotg.lue.com is invalid'" } ] }, "summary": { "Contacts": { "success": 0, "fail": 1, "existing": 0, "updated": 1 } } } ``` Here `id` is the id in Salesforce and `externalId` (if passed on the record) is the id in the source system. If you prefer to work with [VSCode's Debugger](https://code.visualstudio.com/docs/editor/debugging), you can run the target with the following configuration: ```json theme={null} { "name": "target-salesforce", "type": "python", "request": "launch", "justMyCode": false, "program": "../target_salesforce/target.py", "cwd": "ABSOLUTE_PATH_TO_TARGET_DIRECTORY/target-salesforce/.secrets", "args": ["<", "data.singer", "--config", "config.json", ">", "state.json"], "console": "integratedTerminal", "python": "ABSOLUTE_PATH_TO_TARGET_DIRECTORY/target-salesforce/.venv/bin/python" } ``` # Running taps Source: https://docs.hotglue.com/custom-connectors/taps Learn how to run custom taps using the Singer SDK # Background A tap reads and processes data from an API or Database. This involves two separate processes: 1. **Discovery**: Generating a catalog of the available streams (aka tables), including metadata such as primary keys and available fields 2. **Syncing**: Reading data from streams and writing the resulting records according to the [**Singer spec**](https://www.singer.io/) # Setting up a local tap environment ## Virtual Environments Dependencies can differ from tap to tap, so it is best to use a virtual environment to isolate the tap's Python dependencies. You can create a virtual environment named `.venv` in your tap workspace with: ```bash theme={null} python -m venv .venv ``` You can then enter the virtual environment with: ```bash theme={null} source .venv/bin/activate ``` Finally, you can install the tap's dependencies depending on how they are specified: | Dependency File | Command | | :-: | :-: | | `requirements.txt` | `pip install -r requirements.txt` | | `setup.py` | `pip install -e .` | | `pyproject.toml` | `pip install -e .` | ## Config Both the **Discover** and **Sync** processes require a valid config, which will include fields like API keys, OAuth credentials, and configuration flags. For example: ```json theme={null} { "client_id": "...", "client_secret": "...", "refresh_token": "...", "access_token": "...", "start_date": "2025-01-25T00:00:00Z", } ``` Most taps will include information about the required config values in their README's. If you want to try to reproduce the sync output of a particular [Hotglue job](/key-concepts/jobs/sync-jobs), you can download the job folder on your Hotglue job page: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/DownloadJobImg.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=d34e7a2e14d2d6f8fe21646164825b99) > 💡 To keep your workspace clean, create a `.secrets` folder to store your `config.json`. Run all tap commands out of this folder to make sure your catalogs and output data stay separate from relevant code. ## Using the Hotglue Access Token Endpoint For OAuth connectors, you can have the tap use the [access token endpoint](https://docs.hotglue.com/api-reference/access-tokens/retrieve-access-token) instead of refreshing the token locally by: **1. Adding this flag to your `config.json`:** ```json theme={null} { "_refresh_token_via_hg_api": true, ... } ``` **2. Setting the following environment variables:** | Variable | Description | | :-: | :- | | `TENANT` | Your tenant ID | | `API_KEY` | Your Hotglue API key | | `FLOW` | The flow ID | | `ENV_ID` | The environment ID | | `TAP` | The tap ID (e.g. `exact`) | ```bash theme={null} TENANT="" API_KEY="" FLOW="" ENV_ID="" TAP="" ``` # Running a Discover Within your virtual environment, you can invoke the tap from your command line. For example, if your tap was called `tap-Salesforce`, you could run a discover with: ```bash theme={null} tap-salesforce --config PATH_TO_CONFIG/config.json --discover > catalog.json ``` If the discover runs successfully, this will generate a file called `catalog.json` with information about the available streams and fields: ```json theme={null} { "streams": [ { "tap_stream_id": "...", "replication_key": "LastModifiedDate", "replication_method": "INCREMENTAL", "key_properties": [ "ID" ], "schema": { .... } } ... ] } ``` If you prefer to work with [VSCode's Debugger](https://code.visualstudio.com/docs/editor/debugging), you can run a discover with the following configuration: ```json theme={null} { "name": "tap discover", "type": "python", "request": "launch", "program": ".../PATH_TO_ENTRY_SCRIPT", // e.g., .../tap_salesforce/tap.py "cwd": "ABSOLUTE_PATH_TO_DIRECTORY_TO_RUN_COMMAND_FROM", "args": [ "--config", "config.json", "--discover", ">", "catalog.json" ], "justMyCode": false, "python": "ABSOLUTE_PATH_TO_TAP_DIRECTORY/.venv/bin/python", "console": "integratedTerminal" } ``` # Selecting Streams and Fields The next step of the syncing process is to select which streams and fields you want to sync. We recommend doing this with the [Singer-Discover Command Line Utility](https://github.com/hotgluexyz/singer-discover). ```bash theme={null} pip install https://github.com/hotgluexyz/singer-discover/archive/master.zip ``` Once installed, you can generate a `catalog-selected.json` with: ```bash theme={null} singer-discover --input catalog.json --output catalog-selected.json ``` You will then be prompted to select your streams ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/singer_discover_cli.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=8d68b46641310b739b520a9e5e1870f9) This will generate a new catalog called `catalog-selected.json` that includes your selection metadata. # Running a Sync You can now sync the streams selected in your `catalog-selected.json`. If your tap is named `tap-Salesforce`, you could run a sync with: ``` tap-salesforce --config config.json --catalog catalog-selected.json > data.singer ``` This will write the streams to a `data.singer` file according to the [**Singer spec**](https://www.singer.io/). If you prefer to work with [VSCode's Debugger](https://code.visualstudio.com/docs/editor/debugging), you can run a sync with the following configuration: ```json theme={null} { "name": "tap sync", "type": "python", "request": "launch", "program": ".../PATH_TO_ENTRY_SCRIPT", // e.g., .../tap_salesforce/tap.py "cwd": "ABSOLUTE_PATH_TO_DIRECTORY_TO_RUN_COMMAND_FROM", "args": [ "--config", "config.json", "--catalog", "catalog-selected.json", ">", "data.singer" ], "justMyCode": false, "python": "ABSOLUTE_PATH_TO_TAP_DIRECTORY/.venv/bin/python", "console": "integratedTerminal" } ``` # Target CSV Source: https://docs.hotglue.com/custom-connectors/target-csv Learn how to convert Singer data to CSV Due to storage and efficiency drawbacks with Singer data, hotglue supports automatically converting the singer output of a standard tap into CSV, which is more digestible for transformation scripts. See [intermediary formats](/key-concepts/jobs/intermediary-formats) for more information. # target-csv target-csv is a singer target which takes in singer data and outputs the data's corresponding csv. When developing locally with the SingerSDK, we recommend using target-csv to easily inspect and validate your data. ## Installation To install target-csv, first create a virtual environment. We recommend creating this environment globally so you can access it everywhere: ```bash theme={null} python -m venv ~/env/target-csv ``` Next, enter that virtual environment: ```bash theme={null} source ~/env/target-csv/bin/activate ``` Next, install target-csv: ```bash theme={null} pip install git+https://github.com/hotgluexyz/target-csv.git ``` ## Usage Suppose you have a file in your local directory called `data.singer` that you want to convert. First enter your virtual environment: ```bash theme={null} source ~/env/target-csv/bin/activate ``` Then simply run: ```bash theme={null} cat data.singer | target-csv ``` If your singer data is malformed, you should see an error message explaining the issue. If the CSV conversion succeeds, you should see a CSV file for each stream in your singer data. # Target Parquet Source: https://docs.hotglue.com/custom-connectors/target-parquet Learn how to convert Singer data to Parquet Due to storage and efficiency drawbacks with Singer data, hotglue supports automatically converting the singer output of a standard tap into Parquet, which is more digestible for transformation scripts. See [intermediary formats](/key-concepts/jobs/intermediary-formats) for more information. # target-parquet target-parquet is a singer target which takes in singer data and outputs the data's corresponding parquet. When developing locally with the SingerSDK, we recommend using target-parquet to easily inspect your data. ## Installation To install target-parquet, first create a virtual environment. We recommend creating this environment globally, so that you can access it everywhere: ```bash theme={null} python -m venv ~/env/target-parquet ``` Next, enter that virtual environment: ```bash theme={null} source ~/env/target-parquet/bin/activate ``` Next, install target-parquet in your virtual environment: ```bash theme={null} pip install git+https://github.com/hotgluexyz/target-parquet.git ``` ## Usage Suppose you have a file in your local directory called `data.singer` that you want to convert. First enter your virtual environment: ```bash theme={null} source ~/env/target-parquet/bin/activate ``` Then simply run: ```bash theme={null} cat data.singer | target-parquet ``` If your singer data is malformed, you should see an error message explaining the issue. If the Parquet conversion succeeds, you should see a Parquet file for each stream in your singer data. # Building targets Source: https://docs.hotglue.com/custom-connectors/targets Learn how to build custom targets using the hotglue SDK # Background A target processes and writes data to an API or Database. It includes the logic to authenticate, handle errors and output the summary of the processed records. # Initial Setup Install the `cookiecutter` Python package via pip ```jsx theme={null} pip install cookiecutter ``` Download the target hotglue sdk by running this command ``` cookiecutter https://gitlab.com/hotglue/target-hotglue-sdk.git --directory="cookiecutter/target-template" ``` Fill `destination_name` with the target name (capitalized), the author name, select "Per record" as the serialization method, and choose the authorization method (OAuth2 or Bearer token). ![Screen Shot 2024-03-14 at 8.20.44 PM.png](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-connectors/images/Screen_Shot_2024-03-14_at_8.20.44_PM.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=6e1952180086cc778a6493d16896212c) Enter the the newly created folder and install the package locally in editable mode, so your changes are reflected immediately for testing ```jsx theme={null} pip install -e . ``` # Target structure The folders and file structure of the target should look like this: ``` .secrets/ # It contains all the input (config.json, data.singer) and output(target-state) files target_example/ auth.py # logic to authenticate to be able to send requests to the API client.py # base sink attributes and methods sinks.py # custom sinks for each endpoint target.py # target class and main file. ``` # target.py The target class is the entry point of the target execution. Target name, available sinks and config fields should be defined here. ### Define the config.json schema In `target.py` define all required values in the config file, such as username, password, api\_key, client\_id, etc ```python theme={null} class TargetExample(TargetHotglue): config_jsonschema = th.PropertiesList( th.Property("username", th.StringType, required=True), th.Property("password", th.StringType, required=True), th.Property( "url_base", th.StringType, ), ).to_dict() ``` ### List the available sinks Import all sinks (Check below to see how to create a sink) ```python theme={null} class TargetExample(TargetHotglue): SINK_TYPES = [VendorsSink, ItemsSink, PurchaseOrdersSink] config_jsonschema = th.PropertiesList( th.Property("username", th.StringType, required=True), th.Property("password", th.StringType, required=True), th.Property( "url_base", th.StringType, ), ).to_dict() ``` # client.py `client.py` contains all the common functions and properties, such as the api base url and the authentication logic within a **base sink**. You can overwrite any of the prebuilt functions here and they will be applied to all sinks The base sink should be a child class from either of these Hotglue sinks: * For Per record serialization method it should inherit from `HotglueSink` * For Per batch serialization method it should inherit from `HotglueBatchSink` ### Common Attributes * `base_url`: The base url of the API * `http_headers`: Any header that should be sent when making the request. * `MAX_SIZE_DEFAULT`: When making a target with per batch serialization methos, this attribute defines the amount of records that will be processed and passed into the `make_batch_request` function. ### Authentication The authentication should be defined in the base sink. If the logic is simple could be added here as well and in cases like OAuth is a good practice to create an auth.py file containing the logic. These are some of the common authentication methods used and how they can be added to the base sink. #### Basic Authentication The basic auth logic can be added as a property or function in the base sink and passed in the headers. ```python theme={null} class ExampleBaseSink(HotglueSink): base_url = "https://www.my_example_api.com" @property def authenticator(self): user = self.config.get("username") passwd = self.config.get("password") token = b64encode(f"{user}:{passwd}".encode()).decode() return f"Basic {token}" @property def http_headers(self): # any headers that should be sent return { "Authorization": self.authenticator } ``` #### API Key authentication The Api Key can be passed directly in the headers. ```python theme={null} class ExampleBaseSink(HotglueSink): base_url = "https://www.my_example_api.com" @property def http_headers(self): # any headers that should be sent return { "Api-Key": self.config.get("api_key") # assuming the api_key is present in the config file } ``` #### OAuth Authentication In the case of OAuth an Authentication class can be created in a separate file. And then imported into the base sink. ```python theme={null} class ExampleSink(HotglueSink): @property def base_url(self) -> str: base_url = f"" return base_url @property def authenticator(self): # basic authentication example user = self.config.get("username") passwd = self.config.get("password") token = b64encode(f"{user}:{passwd}".encode()).decode() return f"Basic {token}" ``` # auth.py This class will be responsible to generate an access token to make requests to the API. The auth class should be called in the base sink class. ### Notes * In case of OAuth with refresh token the target will only handle the logic to refresh the token, the authorization process should be done before and the refresh\_token should be already in the config file. * In hotglue, the authorization process is handled out of the box. ### Main properties * `auth_headers`: Inside we can validate if the token is valid, call the function to request a new token and structure the access token. It should return a dict with the Authorization key and the access\_token to be sent in the requests made to the API. * `oauth_request_body`: It builds the payload to be sent when making the request to obtain a new access token. ### Main functions * `is_token_valid`: It validates if the token is still valid or not to be used. It should return a boolean. * `update_access_token`: It makes a request to generate a new access token.\ In cases of rotating refresh tokens or if we need to save the new access token in the config file, we need to add an init statement in the Auth class, Target class and the Base Sink class. ### Sample auth.py ```python theme={null} class ExampleAuthenticator: """API Authenticator for OAuth 2.0 flows.""" def __init__( self, target, auth_endpoint: Optional[str] = None, ) -> None: """Init authenticator. Args: stream: A stream for a RESTful endpoint. """ self.target_name: str = target.name self._config: Dict[str, Any] = target._config self._auth_headers: Dict[str, Any] = {} self._auth_params: Dict[str, Any] = {} self.logger: logging.Logger = target.logger self._auth_endpoint = auth_endpoint self._config_file = target.config_file self._target = target @property def auth_headers(self) -> dict: if not self.is_token_valid(): # validate token self.update_access_token() #update token if not valid result = {} result["Authorization"] = f"Bearer {self._config.get('access_token')}" return result @property def oauth_request_body(self) -> dict: """Define the OAuth request body""" return { "refresh_token": self._config["refresh_token"], "grant_type": "refresh_token", "client_id": self._config["client_id"], "client_secret": self._config["client_secret"], } def is_token_valid(self) -> bool: access_token = self._config.get("access_token") now = round(datetime.utcnow().timestamp()) expires_in = self._config.get("expires_in") if expires_in is not None: expires_in = int(expires_in) if not access_token: return False if not expires_in: return False return not ((expires_in - now) < 120) def update_access_token(self) -> None: token_response = requests.post( self._auth_endpoint, data=self.oauth_request_body, headers={} ) token_json = token_response.json() self.access_token = token_json["access_token"] self._config["access_token"] = token_json["access_token"] self._config["refresh_token"] = token_json["refresh_token"] self._config["expires_in"] = int(token_json["expires_in"]) with open(self._target.config_file, "w") as outfile: json.dump(self._config, outfile, indent=4) ``` # sinks.py Create a sink per each endpoint in `sinks.py` ### Main functions Most of the target logic is defined in `target-hotglue` sdk, in most cases only 2 functions logic need to be defined. * `preprocess_record`: This functions reads each record from the `data.singer` and builds the payload that will be sent to the API. Here is where data can be mapped or customized logic to build the payload can be added.\ It should return the payload to be sent to the API. * `upsert_record`: It receives the payload returned by `preprocess_record` function and it sends it to the API.\ It should return id, status, state. * **id**: the API provided id of the created or updated record * **status**: a boolean that tells us if the record was sent succesfully, * **state**: data to be written in the `target-state.json` commonly an empty dict. If the record was updated instead of created we can add it to the state: ```python theme={null} state["is_updated"] = True ``` **Note**: any exception or error in the `process_record` function won't stop the target, the error will be written in the `target-state.json` file together with the `externalId` provided in the `data.singer`, and the target will continue and read the next record. ### Samples ```python theme={null} class ContactsSink(ExampleSink): endpoint = "/contacts" name = "Contacts" # should have the same name as the record that will be ingested ``` You can add the method `preprocess_record` to the ContactsSink class, this will take the input data and transform it into the payload we pass to the endpoint ```python theme={null} class ContactsSink(ExampleSink): endpoint = "/contacs" name = "Contacts" def preprocess_record(self, record: dict, context: dict) -> None: payload = { "Name": record.get("name"), "LastName": record.get("last_name"), "Currency": record.get("currency"), } return payload ``` Add the method `upsert_record` to the ContactsSink class, here the payload created from `preprocess_record` will be sent to the api ```python theme={null} def upsert_record(self, record: dict, context: dict): state_updates = dict() # initialize the state to save in the state status, and the id of the new created contact # basic request structure if record: vendor = self.request_api( "POST", endpoint=self.endpoint, request_data=record ) vendor_id = vendor.json()["id"] return vendor_id, True, state_updates # required, or the request will be considered as failed ``` 💡 Note: if the logic inside this function will be the same for all sinks, this method can be added this to ExampleSink class in `client.py` instead of each sink class. # target-state.json The target state stores the **bookmarks** which is an array of all the outputs that come from `upsert_record`. It holds the id of the newly created or updated records, or if an error ocurred it contains the reason of the error and the `externalId` data to recognize which record has failed. It stores the **summary** which is a count of 4 types of records: * *success*: Count of created and updated records, if updated is not defined in the `upsert_record` function. * *failed*: Count of records that failed to be created or updated. * *existing*: Count of any dupplicated records that were read, the target uses the `externalId` to determine this. * *updated*: Count ofupdated records, this counts only works if defined in `upsert_record`. Example: ```json theme={null} { "bookmarks": { "Bills": [ { "hash": "994e64ce06a996df7c24fc70543969a33352efe2114805e49ad01ca42e6862c5", "success": true, "id": "B-7890" } ] }, "summary": { "Bills": { "success": 1, "fail": 0, "existing": 0, "updated": 0 } } } ``` # Testing the target locally ### Input Files #### config.json This file stores all the credentials needed to send data to the API. Flags or additional data can be saved here for customized logic *Example*: ```json theme={null} { "username": "user_12345&", "password": "asdzxc098", "required_header_value": "header_required" } ``` #### data.singer All Singer SDK targets accept a `jsonl` (JSON lines) input, we typically call it `data.singer` which should be Singer formatted records. **Note:** Each record should have an `externalId` field, this will serve as a primary key to update the target-state if errors happen. **Example**: ```jsx theme={null} {"type": "SCHEMA", "stream": "Bills", "schema": {"type": ["object", "null"], "properties": {"vendorId": {"type": ["string", "null"]}, "totalAmount": {"type": ["number", "null"]}, "currency": {"type": ["string", "null"]}, "externalId": {"type": ["string", "null"]}}}, "key_properties": []} {"type": "RECORD", "stream": "Bills", "record": {"vendorId": "V-1234", "totalAmount": 23.56, "currency": "USD", "externalId": "12345"}} {"type": "STATE", "value": {}} ``` ### Running the target Now to run the target you can do this: ```jsx theme={null} cat data.singer | target-salesforce --config config.json ``` You can also set this up a debug config in vscode in the `launch.json` by setting a definition that looks like this: ```jsx theme={null} { "name": "target-salesforce", "type": "python", "request": "launch", "justMyCode": false, "program": "../target_salesforce/target.py", "cwd": "targets/target-salesforce/.secrets", "args": [ "<", "data.singer", "--config", "config.json" ], "console": "integratedTerminal", "python": ".env/target-salesforce/bin/python" } ``` # Automations Source: https://docs.hotglue.com/environment-settings/automations Send webhook notifications when events occur in your environment Automations send a notification when a selected event occurs in an environment. Use them to notify your application or internal tools when integrations are connected, jobs run, tenants change, schedules are updated, and more. Each automation applies only to the environment where you create it. To configure the same behavior in staging and production, create an automation in each environment. ## Prerequisites * Automations must be enabled for your organization. * You must be an **Admin** to create, edit, enable, disable, or delete automations. **Developers** can view automations and destinations. * You need an HTTP or HTTPS endpoint that can accept JSON `POST` requests. ## Create an automation 1. Open the environment where you want to receive notifications. 2. In the environment navigation, select **Automations**. 3. Select **New Automation**. 4. Enter a name and choose whether the automation is enabled when you save it. 5. Select an event. 6. Select a destination, then select **Save Changes**. The event selector shows a sample payload for the selected event. An automation uses the default payload shown there. ## Configure a destination Destinations are reusable webhook endpoints. Create one from **Manage Destinations** while creating an automation, or select **Destinations** on the Automations page. 1. Select **Add Destination**. 2. Enter a name and your **Webhook URL**. 3. Optionally enter a [**Signing secret**](#verify-webhook-requests). 4. Select **Save Changes**, then choose the destination for your automation. Hotglue sends a JSON `POST` request with a `Content-Type: application/json` header. A response outside the `2xx` range is treated as a failed delivery and is retried up to three times. > [!NOTE] > > Webhook is the only destination type currently available. Slack and email destinations are not yet supported. ## Verify webhook requests When you set a signing secret, Hotglue adds an `X-Hub-Signature` header containing the HMAC-SHA1 signature of the raw request body. Use a timing-safe comparison to verify the request before processing it. ```javascript webhook-verification.js theme={null} import crypto from 'node:crypto'; const signature = request.headers['x-hub-signature']; const payload = request.rawBody; const expected = crypto .createHmac('sha1', process.env.HOTGLUE_WEBHOOK_SECRET) .update(payload) .digest('hex'); const isValid = signature && signature.length === expected.length && crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected)); if (!isValid) { throw new Error('Invalid Hotglue webhook signature'); } ``` ## Manage automations and destinations Use the toggle on an automation to enable or disable it without deleting its configuration. You can also edit or delete an automation from the Automations page. Destinations can be used by more than one automation. Before deleting a destination, remove it from every automation that references it. # Environment Variables Source: https://docs.hotglue.com/environment-settings/environment-variables Example overview page before API endpoints ## Overview Environment variables in Hotglue allow you to dynamically configure various settings that your ETL transformation scripts can utilize. This enables easier maintenance and scaling of your integration tasks. Commonly, environment variables are used for API URLs, export formats, and other dynamic settings. *** ## Accessing the Environment Variables Setting Page 1. Log in to your Hotglue account. 2. Navigate to the **Settings** tab on the sidebar. 3. Click on the **Environment Variables** option. *** ## Adding Environment Variables To add an environment variable: 1. Navigate to the **Environment Variables** setting page. 2. Add a **Key** and **Value** for your variable. 3. Click **Save** to create the new variable. 4. You can always click the ✎ **pencil** icon to edit an existing variable *** ## Default Environment Variables ### DEFAULT\_EXPORT\_FORMAT * **Description**: Defines the default export format for all ETL transformation scripts. * **Accepted Values**: `json`, `csv`, `parquet` ## Usage in ETL Transformation Scripts To use environment variables in your ETL transformation scripts, you can utilize the `os.environ` Python library as shown below: ```python Python theme={null} import os api_url = os.environ.get('API_URL') ``` *** ## Best Practices * **Naming Convention**: Use all upper-case letters and underscores to define variable names (e.g., `API_URL`). * **Default Values**: Always include default values in your ETL scripts for environment variables when applicable. * **Validation**: Implement validation checks in your ETL scripts to ensure that environment variables contain expected types and values. * **Consistency**: Use consistent naming and value types across multiple environment variables to make the system more intuitive and easier to manage. # GitHub App Source: https://docs.hotglue.com/environment-settings/github-app Connect private GitHub repositories to hotglue # Private GitHub repositories The Hotglue GitHub App gives hotglue read access to the private GitHub repositories that contain your custom taps and targets. Hotglue uses short-lived installation tokens, so you do not need to create or maintain a GitHub personal access token. ## Prerequisites * Private connector repositories must be enabled for your Hotglue organization. * You must be a Hotglue organization administrator to configure the integration. * You need permission to install or request the GitHub App for the GitHub account or organization that owns the repositories. ## Connect GitHub **1. Open the GitHub integration** In Hotglue, open **Account Settings**, select **Integrations**, and find **GitHub**. **2. Install the Hotglue GitHub App** Select **Connect**, then choose the GitHub account or organization that owns your private connector repositories. If the organization restricts app installations, a GitHub organization owner must approve the request. **3. Choose repositories** Grant access to all repositories or select the repositories that contain your private taps and targets. Every repository used by a private connector must be included. **4. Confirm the connection** After GitHub completes the installation, return to Hotglue. The integration displays **Connected** and whether it can access all or selected repositories. ## Import a private connector 1. Open your environment and go to **Settings** > **Connectors**. 2. Select **Create New** > **Import a Git Repo**. 3. Enter the GitHub repository URL and select **Private** under **Repository access**. 4. Complete the connector details and select **Create Template**. The imported connector is automatically marked as private. If you configure a connector manually, set `is_private_repo` to `true`: ```json theme={null} { "install_uri": "git+https://github.com/your-org/tap-example.git@v1.0.0", "is_private_repo": true } ``` > [!WARNING] > > A connected installation does not guarantee access to every repository. If you selected individual repositories on GitHub, make sure the repository in the install URI is included. ## Manage repository access In **Account Settings** > **Integrations**, select **Manage** next to GitHub to change which repositories the App can access. Repository access is managed on GitHub. Select **Disconnect** to uninstall the Hotglue GitHub App and revoke its access to private repositories. This can also disconnect other Hotglue organizations that use the same GitHub App installation. ## Troubleshooting * **Repository cannot be installed:** Select **Manage** and confirm that the repository is included in the GitHub App installation. * **Attention needed:** Select **Reconnect** to restore repository read access or replace an inaccessible installation. * **Installation requires approval:** Ask a GitHub organization owner to approve the Hotglue GitHub App, then start the connection again. * **Setup window does not open:** Allow pop-ups for Hotglue and retry the connection. # Job settings Source: https://docs.hotglue.com/environment-settings/job-settings Set up job settings and webhook monitoring # Basic Settings | Setting | Description | | - | - | | Force full sync | This will run *full* historical sync jobs every time, including records that have already been synced. | | Never sync historical data | This prevents syncing any historical data. When enabled, the configured start date is replaced with the current date/time. Only records created or updated after the tenant links will be synced. | | Force discover | Force discover will refresh the field map before every sync job. This makes jobs run longer, but is useful when each user has different fields. | | Automatically trigger a job when an integration is linked | This will run an initial full sync job as soon as your customer links an integration. | | Trigger a discover when an integration is linked | This will refresh the field map after a user links. This is especially useful if you want your users to map fields before running the first job. | | Automatically rollback job on failure | When a critical error is detected, this setting will automatically roll back the entire job. | | Automatically enable default sync schedule | This will create a sync schedule every time a user links a new source. This only applies to sources synced after this setting is enabled. Learn more about [default sync schedules here](https://docs.hotglue.com/docs/jobs-scheduling#using-a-default-sync-schedule). | | Save snapshots even when jobs fail | By default, snapshots will only persist if a job is successful. Turning this on will allow snapshots to be updated whether or not the associated job succeeds. Learn more [about snapshots here.](https://docs.hotglue.com/docs/transformations-snapshots) | # Datadog integration You can configure hotglue to push job events (success or failures) directly to your Datadog events to maintain observability in one platform. To configure, head to your Environment Job Settings, and configure your Datadog Region and API Key. Once these settings are saved, hotglue will automatically begin pushing job events to your Datadog account! ![3018](https://files.readme.io/26cf3b2-Screen_Shot_2022-06-09_at_11.10.04_AM.png) Datadog Settings # Slack integration For a simpler notification system, you can configure a free Slack app to get notified about failed jobs. 1. Create a [free Slack app](https://api.slack.com/messaging/webhooks). 2. Paste your new incoming webhook URL into hotglue. This URL will look something like this: ``` https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX ``` # Custom storage In certain cases you may want to *snapshot* or *cache* the data that hotglue processes during a specific sync job. By default this is done using hotglue's infrastructure, but you can configure this to be done using your own **AWS S3 buckets**. To store either the snapshot or cache data in your own S3 bucket, you need to: 1. Create an S3 bucket that hotglue will use during jobs 2. Create an IAM user for hotglue to access this S3 bucket with programmatic credentials (Access Key Id / Secret Access Key pair) 3. Create an IAM permission policy and attach it to the IAM user. The policy should be as follows: ``` { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:DeleteObject", "s3:GetObject", "s3:PutObject", "s3:PutObjectAcl", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::", "arn:aws:s3:::/*", "arn:aws:s3:::", "arn:aws:s3:::/*" ] } ``` 1. Finally, you can save the bucket name, access key id, and secret access key to your hotglue settings, as pictured below: ![](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/custom-storage.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=1763e0985d0454533a4065cee1f89eff) # Private Repositories > [!NOTE] > > This feature is not available to customers enrolled in the Hotglue Startup Program. To use a private GitHub repository, connect the [Hotglue GitHub App](/environment-settings/github-app). The App provides Hotglue jobs with a way to generate short-lived credentials for the repositories selected during installation. To mark a connector as private, use the `is_private_repo` [connector setting](/key-concepts/connectors/v1-sources/settings#is-private-repo). # AWS VPC Sharing > [!NOTE] > > This feature is only available on the Enterprise Platform License. ### Overview On our enterprise tier we offer the ability to leverage Amazon Virtual Private Cloud (VPC) sharing. By leveraging a shared VPC setup, data transfers between your system and hotglue remain private and secure, avoiding exposure over the public internet. [hotglue: AWS VPC Peering demo](https://www.loom.com/embed/049fe9b831bd4fc28d73dd1b3cf9003f?sid=7e59439d-1f3c-4c3a-9051-60b588a05523) ### Prerequisites To use this feature, ensure you have the following: 1. AWS Account: Administrator access to manage VPC and S3 resources. 2. VPC Sharing Permissions: Confirm that your organization allows setting up VPC sharing. ### Step 1: Receive VPC Information from hotglue Your hotglue account manager will provide the following details: * VPC ID * Subnet IDs * Route table information * Security group configuration ### Step 2: Establish VPC Peering Connection 1. Navigate to the **VPC Dashboard** in your AWS Management Console. 2. Select **Peering Connections** and click **Create Peering Connection**. 3. Provide the following details: * **Requester VPC**: Select your existing VPC. * **Accepter VPC**: Enter the VPC ID provided by hotglue. 4. Click **Create Peering Connection**. 5. Notify hotglue so they can accept the peering request on their side. ### Step 3: Update Route Tables 1. In the **VPC Dashboard**, go to **Route Tables**. 2. Select the route table associated with your VPC. 3. Click **Edit Routes** and add a new route: * **Destination**: CIDR block provided by hotglue. * **Target**: Select the peering connection created in Step 2. 4. Save the route. ### Step 4: Configure Security Groups 1. Go to **Security Groups** in the VPC Dashboard. 2. Select the security group associated with your resources. 3. Click **Edit Inbound Rules** and add a rule to allow traffic from the hotglue VPC. * **Type**: Custom TCP Rule (or as per your application needs) * **Protocol**: TCP * **Port Range**: Define required ports, e.g. 1. `443` for HTTPS 2. `3306` for MySQL * **Source**: hotglue-provided CIDR block 4. Save the changes. For more assistance, contact hotglue support. # Webhooks Source: https://docs.hotglue.com/environment-settings/webhooks Integrate hotglue with your own workflow by configuring a webhook # Configure a webhook To configure a webhook for your environment, go to **Settings** > **Jobs** > **Monitoring & Alerts**. For each webhook that is available to configure, there are two fields: | Name | Description | | - | - | | Webhook URL | This is the webhook endpoint you want hotglue to send POST requests to | | Webhook Secret | Optional - if provided, hotglue will generate a signature of every payload using this secret and include it as the `X-Hub-Signature` in the request headers. Used to verify the payload is from hotglue. | # Available Webhook Subscriptions You can subscribe to any of three primary types of events using hotglue webhooks: 1. **Job Lifecycle** 2. **Discover** 3. **Connection** Each webhook event is a JSON POST to your configured endpoint, optionally signed using the webhook secret that you define. ## 1. Job Lifecycle Webhook This is the primary subscription that most hotglue workflows rely on. The job lifecycle webhook sends a POST request to your hook every time a job moves forward in the job lifecycle. You can read about the [job lifecycle here](https://docs.hotglue.com/docs/jobs-lifecycle). ### Example payload ```json JSON theme={null} { "job_id": "tVN_B", "env_id": "dev.hotglue.com", "flow_id": "JClkCC05S", "job_name": "test_job:KWjsnRTyp", "tenant": "1414_1", "started_by": "1414_1", "s3_root": "1414_1/flows/JClkCC05S/jobs/2024/10/1/06/05/tVN_B", "start_time": "2024-10-06T20:14:59.957270+00:00", "state": {}, "tap": "salesforce", "target": "bigquery", "connector_id": null, "job_type": null, "status": "JOB_COMPLETED", "scheduled_job": true, "sync_type": "full_sync", "override_start_date": null, "override_end_date": null, "override_field_map": null, "override_source_config": null, "override_target_config": null, "override_lifecycle_webhook": null, "task_id": "3430414a60df4efdb9aa7d7abaf877fc", "task_type": "STANDARD", "task_definition": { "id": "hotglue-executor-v2:4", "memory": 32768, "cpu": 8192 }, "discover_install_uri": "git+https://github.com/hotgluexyz/tap-salesforce.git@v1.0.12", "metrics": { "recordCount": { "Opportunity": 21029, "Lead": 285990, "User": 360, "Account": 742570 } }, "data_sizes": { "sync_output": 2812.21, "etl_output": 7957.72, "snapshots": 0, "total": 10769.93 }, "last_updated": "2024-10-07T07:50:28.076586+00:00", "error": null, "status_timestamp": { "SYNC_STARTED": 1728245795146, "ETL_STARTED": 1728245807884, "EXPORT_STARTED": 1728249071639 }, "resources_usage": { "memoryUsage": 22014.92 }, "target_install_uri": "s3://hotglue-prod.admin/env_zips/target-bigquery/target_bigquery-v0_11_11.py3_7.zip" } ``` ## 2. Discover Webhook This is a useful subscription if you have workflows that rely on a successful discover completing, such as custom field mapping or in-widget table selection. Like the job lifecycle webhook, the discover webhook sends a POST request to your hook every time a discover task moves forward in the discover lifecycle. The discover lifecycle has three possible events: * `DISCOVER_STARTED` * `DISCOVER_SUCCESS` * `DISCOVER_FAILED` ### Example Payload ```json JSON theme={null} { "connector": "salesforce", "env_id": "dev.hotglue.com", "flow_id": "JClkCC05S", "status": "DISCOVER_SUCCESS", "tenant": "1414_1", "timestamp": "2024-10-07T07:50:28.076586+00:00" } ``` ## 3. Connection Webhook This is a useful subscription if you would like to take action when users link or unlink an integration in hotglue, or would otherwise like to create an internal database table to monitor connections. The connection webhook sends a POST request to your hook whenever a `linkedSource`, `linkedTarget`, or `linkedConnector` is created, overwritten, or removed. ### Example Payload ```json JSON theme={null} { "tenant": "1414_1", "flow_id": "JClkCC05S", "env_id": "dev.hotglue.com", "connector": "tap", "connector_type": "connector", "event": "LINK", "timestamp": "2024-10-07T07:50:28.076586+00:00", "event_id": "a8edda26-62f5-4b33-9434-c31f21d34c6c", "first_link": true } ``` # Validating the signature If you've chosen to set a webhook secret, we will send an `X-Hub-Signature` in the request headers to your webhook URL. The purpose of this is to verify that the payload came from hotglue. See below for sample logic for how to validate the signature using JavaScript. ```javascript webhook-verification.js theme={null} // Get the X-Hub-Signature header const signature = req.normalizedHeaders['x-hub-signature']; // Get the payload of the webhook as a string const payload = typeof req.rawBody == "object" ? JSON.stringify(req.rawBody) : req.rawBody; // Get your webhook secret const secret = hotGlue.webhookSecret; // Compute the signature using the above parameters const computedSignature = crypto.createHmac('sha1', secret).update(payload).digest("hex"); const checksum = Buffer.from(signature, 'utf8'); const newChecksum = Buffer.from(computedSignature, 'utf8'); // Verify that the signature matches the X-Hub-Signature that was passed to you if (checksum.length !== computedSignature.length || !crypto.timingSafeEqual(newChecksum, checksum)) { // This signature is invalid, and was not sent by hotglue console.error("Unable to verify Signature " + payload); return false; } // The signature was valid, it is safe to act on this webhook payload console.log("Verified Payload Signature !"); return true; ``` # White-label Source: https://docs.hotglue.com/environment-settings/white-label Fully white-label your user OAuth experience The **callback URI** (also known as a redirect URI or callback URL) is an essential part of OAuth. It allows Hotglue to obtain the tokens required to access your users' resources. Hotglue's default callback URL is: `https://hotglue.xyz/callback` For OAuth integrations, users will see this page during the OAuth redirect flow after authenticating with the external system. By default, the callback page appears as follows: ![Default Hotglue callback page](https://mintcdn.com/hotglue/NQhsDbUT6K-L4Ha_/images/default%20callback%20.png?fit=max\&auto=format\&n=NQhsDbUT6K-L4Ha_\&q=85\&s=1ffacdb5f51ed5d856bc0144e7376149) ## Customizing the Experience You can customize the visual appearance and branding of this page to match your application. Using the **White Label OAuth Callbacks** settings, you can modify the loader, colors, and displayed text. ![White Label setup interface](https://mintcdn.com/hotglue/NQhsDbUT6K-L4Ha_/images/default%20setup.png?fit=max\&auto=format\&n=NQhsDbUT6K-L4Ha_\&q=85\&s=01f14898e89bbca8d96ff7a399fd0964) ## Callback Image & Background This is the recommended and fastest way to white-label your callback page. Upload a branded loader (such as a loading GIF) or a static image, and configure a **Background Color** using a HEX color code. ### Example Configuration By providing a custom image URL and a HEX color code, you can significantly alter the appearance of the callback page: ![Example of custom white-label settings](https://mintcdn.com/hotglue/NQhsDbUT6K-L4Ha_/images/white%20label%20example%20setup.png?fit=max\&auto=format\&n=NQhsDbUT6K-L4Ha_\&q=85\&s=508035fef682f0902912906807724750) The resulting callback experience is consistent with your application’s branding: ![Customized brand callback page](https://mintcdn.com/hotglue/NQhsDbUT6K-L4Ha_/images/white%20label%20example.png?fit=max\&auto=format\&n=NQhsDbUT6K-L4Ha_\&q=85\&s=e98f390a090a66a96018fc9fd1ff4cfe) *** ## Redirect URL You can configure a custom redirect URL that you own—for example,\ `integrations.{{YOURDOMAIN}}.com` instead of `hotglue.xyz/callback`. Once configured, Hotglue provides two CNAME records that must be added to your DNS settings. ![Custom Redirect URL](https://mintcdn.com/hotglue/VItYG3YR9e8G8GjC/images/Custom%20Redirect%20URL.png?fit=max\&auto=format\&n=VItYG3YR9e8G8GjC\&q=85\&s=677de55d1b580b657f326161eb1b74fe) > **Note:** You must update the redirect URIs in any existing OAuth applications after making this change. ## Hide Loading Text When **enabled**, all loading text is hidden during the OAuth callback process, leaving only the callback image or loader centered on the page. ![Hide loading text](https://mintcdn.com/hotglue/NQhsDbUT6K-L4Ha_/images/hide%20loading%20Text.png?fit=max\&auto=format\&n=NQhsDbUT6K-L4Ha_\&q=85\&s=c47e9175b6426eea95d62765d038a1f1) ## Favicon Use this field to specify a 16×16 pixel image file that will appear in the browser tab for the callback page. ![Favicon image](https://mintcdn.com/hotglue/VItYG3YR9e8G8GjC/images/Favicon.png?fit=max\&auto=format\&n=VItYG3YR9e8G8GjC\&q=85\&s=40dc0a436365105cba0033a1b918c4c4) ## Site Name Optionally override the site name displayed in the browser tab and history for the callback page to match your company or application name. ![Site Name image](https://mintcdn.com/hotglue/NQhsDbUT6K-L4Ha_/images/Site%20Name.png?fit=max\&auto=format\&n=NQhsDbUT6K-L4Ha_\&q=85\&s=45727e1ab1e37541307d1456cbe5479f) # Widget settings Source: https://docs.hotglue.com/environment-settings/widget-settings Learn more about the widget settings The **widget page** allows you to change what your widget looks like and what your users can do with it. There are several options you can configure: ### Color Set a primary color for action buttons, hover effects, and other elements in the widget. Because the background and button text will be white, this color should be dark enough to provide accessible contrast. ### Font Family Specify a font-family to use across the widget. You should start with the font-family you want and end with a generic family for the browser to fall back on. ### Dark Theme By default, the widget uses a light theme with a white background. Toggling this option will display a dark widget instead. ![](https://files.readme.io/dd9ea60-8b14168-Screen_Shot_2022-09-11_at_4.57.52_PM_1-min.png) # Enable in-widget permissions for your users There are two ways to enable additional tabs and configurations in the widget. Some settings, like custom mapping and filters are designed to be dynamically configured in your embed code. Other options, like the ability to run jobs, are configured globally for your environment. By default, your users will only be able to unlink and re-configure credentials via the widget. ### Run jobs This will show users a button to run a new sync job. ### Run full sync jobs This will allow users to run a complete sync job > [!WARNING] > > Note that this will clone *all* historical data again. This can create duplicates in your target if you don't properly handle duplicated data in the script or target. ### Edit sync schedule This will allow users to modify the schedule on which their data is synced. For **Widget v3 (Beta)**, this permission must be on for end users to see and use the **Scheduled data syncs** screen inside the embedded widget. See the [Sync Schedule](/widget-v3/reference/sync-schedule) reference for how that UI behaves once enabled. ### Enable interval schedules When this permission is enabled for your environment, **Widget** shows a **Schedule type** field on the Scheduled data syncs screen so users can choose **interval** (repeat every N minutes or hours) in addition to **fixed** (calendar-style) schedules. ### Enable connector schedules With this option **off** (the default), sync timing is configured once per **flow**. With it **on**, each linked **connector** may have its own schedule (`connector_id`). In the embedded widget, edits made from **Scheduled data syncs** while a connector is in context are written to that connector’s schedule, not only the flow-level schedule. For how this surfaces in callbacks, see [setListeners](/widget-v3/reference/setListeners) and [Sync Schedule](/widget-v3/reference/sync-schedule#flow-level-vs-connector-level-schedules). ### Edit field map This will allow users to modify the field map of what data they want to import from a specific integration. ### View jobs history This will show users a new tab called Job History. This is a simplified list of a user's most recent jobs and the status of those jobs. # FAQ Source: https://docs.hotglue.com/faq Get answers to all your questions on hotglue. ## How does hotglue actually speed up the process of building integrations? Most iPaaS solutions focus on authorization, event triggers, and unified data models. They are generally designed to be low-code, standardized abstractions of external APIs with limited scopes and use cases. hotglue is specifically **not** a low code integration tool – we've found that: 1. Dealing with authorization flows is largely boilerplate, and is not what developers find difficult about creating integrations. Instead, developers want to derive value from their users' data. Although hotglue offers similar authorization management, unified data models, and an [embeddable interface](https://www.npmjs.com/package/hotglue-elements), our focus lies in processing raw data **before** it reaches your backend. 2. Developers prefer granular control over data, and sacrificing that to a drag-and-drop editor typically forces developers to write their own preprocessing code on the output data before it is ingestible. 3. Proprietary connectors leave developers at the whim of the iPaaS vendor's product roadmap. By using open-source connectors, any developer with Python knowledge can build a hotglue-compatible Singer connector. ![](https://files.readme.io/09511cf-format.png) hotglue field selector + Python preprocessing layer *** ## What if I need an integration that isn't currently supported by hotglue? > [!TIP] > > hotglue has over 200 connectors – if you'd like an integration that is not listed on [our connectors page](https://hotglue.com/connectors), let us know. Since hotglue is based on Singer, you can easily create a new Singer tap yourself (for instance, using the [Singer SDK](https://gitlab.com/meltano/singer-sdk)) and use it in hotglue. This way your team maintains flexibility over shipping new integrations even while leveraging the hotglue platform. *** ## How does hotglue compare to Zapier or Integromat? **Zapier** and **Integromat** are good solutions for giving your users self-managed, trigger based connections to their apps. They can both be great tools to spin up integrations quickly and to understand which integrations users want. **hotglue** sits inside your product and functions just like a native integration in your product. This leads to a simpler connection experience for users – instead of setting up a Zap, users just need to authorize their 3rd party app and your software takes care of the rest. With Zapier or Integromat, your users also bear the cost of integrating with your platform. With hotglue, integrations are a feature of your app, and can be embedded anywhere in their user journey. This is useful for onboarding purposes, but also to enable more complex integrations. Zapier and Integromat may excel at transmitting one-off records, but solutions that require bulk data, deep business logic, or data pre-processing usually find Zapier and Integromat insufficient. *** ## Is there a limit to the amount of data hotglue can transfer? hotglue is designed to sync data *incrementally*, meaning the first **sync job** pulls all historical data (from a specific *start date*), and subsequent sync jobs only pull the delta data (new or updated records). hotglue has no specific limitations on the data size per sync, and can adjust these based on your subscription plan. To learn more, shoot us an email at [hello@hotglue.xyz](hello@hotglue.xyz). *** ## Can I sync data both ways with hotglue? Yes! Over 60 of our 200+ integrations support bidirectional syncing. You can write data to supported connectors via the hotglue API, a database, or even your own API. You can also read data to your own API, along with any database or filestore connector in our library. *** ## Can hotglue sync data in real time? hotglue supports real-time triggers for many of our integrations. For example, hotglue can automatically trigger a sync job when a new contact is created in Salesforce, or when a new order is placed in Shopify. However, hotglue is primarily designed for bulk use cases, where you need to clone historical data from an integration, fetch incremental changes, and push data back. Curious to know more? [Book a demo call](https://hotglue.com/demo). *** ## Something else? Don't see the question you're looking for? Shoot us an email: [hello@hotglue.xyz](hello@hotglue.xyz) # Welcome to hotglue Source: https://docs.hotglue.com/introduction The ETL platform to build the integrations your customers want ![Hero Light](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/hero-light.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=3cd67eab13c90f158aec5c002d8071ba) ## What is hotglue? hotglue enables you to build native-feeling integrations with the SaaS tools your customers use. hotglue is **embeddable**, **code-first**, and built on the **Python ecosystem** — enabling developers to build flexible, scalabale integrations without the lock-in of traditional iPaaS tools. ## What's different about hotglue? ### Open source connectors All of hotglue's connectors are completely open source and based on the [Singer spec](https://singer.io/). There are already hundreds of connectors available created by open source contributors [including hotglue](https://github.com/hotgluexyz). ![Source](https://files.readme.io/5ad1733-sources.png) ### Interesting, but why should I care? One of the biggest reasons developers are (rightly) opposed to using an integration platform is because they want to avoid blockers when shipping new features (and integrations). For example, if your users want an integration with a platform hotglue doesn't support, you likely don't want to wait for the hotglue team to add it to their roadmap. Since all hotglue connectors are compatible with Singer, you could easily create a new Singer tap yourself (for instance, using the [Singer SDK](https://gitlab.com/meltano/singer-sdk)). This way your team is assured you can ship new integrations leveraging the hotglue platform, without waiting on our team. Pretty cool, right? ## Stateful integrations hotglue was designed to correlate data across 3rd party systems. For example, hotglue makes it easy to sync Quickbooks Invoices and Salesforce Opportunities, and programmatically match each opportunity to an invoice. This type of behavior is possible because hotglue's integrations are **stateful** – developers have access to a full picture of a user's data through **snapshots**. This makes it easier to build complex integrations while relying on hotglue to deal with orchestration, data integrity, and more. ## Handles non-standardized APIs SaaS APIs are far from unified – extract the data you need before it reaches your product. hotglue comes with a Python-based transformation layer, so developers can write simple transform scripts to standardize data before it gets to your backend. ![960](https://files.readme.io/c3488a5-standardize.png "standardize.png") hotglue jobs + standardizing data *** # What are embedded integration (iPaaS) platforms? Embedded integration platforms enable developers to build native integrations faster and more scalably by sitting within your product. End users connect their data sources within your web app, but the iPaaS handles authentication with the 3rd party system and orchestration of data syncs. ![](https://files.readme.io/b88c7ff-dzone_integrations_talk.png "dzone integrations talk.png") ### Extract hotglue leverages connectors to securely provide access to the most popular data sources out of the box. From Salesforce to HubSpot, we've got you covered. Through the hotglue widget, you can provide users with a simple self-serve interface to connect their data sources to your app with just two lines of code. Read more about how extraction is handled in the hotglue platform here. ### Load All data from your configured connectors is moved to Python processing and consumption by your application. Data never leaves your cloud environment, so your data is safe every step of the way. ### Transform hotglue enables developers to leverage the Python ecosystem to compose transformation scripts. Built with developers in mind, hotglue combines the power of Python modules like Pandas and Dask with the power of AWS, all in a simple always-ready workspace powered by JupyterLab. Read more about the benefits of the embedded integration paradigm [here](https://medium.com/pminsider/an-alternative-strategy-for-solving-etl-extract-transform-load-for-your-product-3dcdbf9ec21f?source=friends_link\&sk=6b9094a96c57e9d4aa4d6ec49b584cda). # Connectors Source: https://docs.hotglue.com/key-concepts/connectors/connectors What are Connectors? # What is a Connector? Each third party integration that your users can interact with is called a **Connector**. Connectors are grouped together within flows. For example, an e-commerce flow may include many different **Connectors**, such as Shopify, Amazon Seller, and WooCommerce. ## Connectors vs Sources vs Targets Connectors can contain **taps**, an integration to read data, and **targets**, an integration to write data. In [V1 jobs](/api-reference/v1/introduction), Connectors are managed separately depending on whether they read or write data: * **Sources** are Connectors that only read data * **Targets** are Connectors that only write data ## What is an available Connector? An **available Connector** is a Connector that you can add to your hotglue flows. You can find a complete list of the [default available Connectors here](https://hotglue.com/connectors). You can also [fork and create custom Connectors](/cli/env) via the Hotglue CLI. ## What is a supported Connector? A **supported Connector** is a Connector that you have configured to be available within a flow. ## What is a linked Connector? A **linked Connector** is a instance of Connector that has been successfully connected to by a particular tenant. # Connector Configuration There are four main configuration options for Hotglue Connectors: 1. Credentials 2. Field maps 3. ETL scripts 4. Triggers ## Config variables Connector configuration values can include variables in curly braces. Hotglue replaces these variables when a job runs. For example, `orders/{tenant}/{date}` can resolve to `orders/acme-corp/202312`. The available variables are: | Variable | Description | | - | - | | `tenant` | Tenant ID | | `root_tenant_id` | Root tenant ID for subtenants | | `tap` | ID of the Connector used by the job | | `date` | Current date (`YYYYMM`) | | `full_date` | Current date (`YYYYMMDD`) | | `flow_id` | Flow identifier | | `job_id` | Internal job ID | | `external_job_id` | External job ID | | `env_id` | Environment ID | Variables can be used in Connector paths and other supported configuration values. See [Using variables in paths](/connectors/s3#using-variables-in-paths) for an example. ## Credentials Connectors generally use one of two types of authorization: APIs and OAuth. Before enabling an OAuth Connector, you must obtain and set up OAuth credentials. 1. Your **Client ID** and **Client Secret** will be found in your company or developer account for that Connector. 2. Scope is used for some OAuth applications to define the data you will be reading or writing. This will prompt tenants to confirm the data permissions you are requesting. ![](https://files.readme.io/3b50c42-Hotglue-Oauth-API-Credentials.png) ## Field maps (V2 Connectors and V1 Sources only) Field maps allow you to choose what data hotglue will pull in a sync job. **The field map** displays a list of **tables** that can be turned on or off. Within each table, **the field editor** displays a list of **fields** that can be pulled or ignored. To modify a field map for a Connector, navigate to your chosen flow, click the "Connectors" (or "Sources" on V1 jobs) tab, then select a Connector to configure it. ![](https://files.readme.io/26fbbb6-Screen_Shot_2022-11-30_at_12.28.07_PM.png) Under configuration, click “customize field map.” From here, you can toggle **tables** on or off by clicking them. ![](https://files.readme.io/6998ef5-Screen_Shot_2022-11-30_at_12.27.32_PM.png) Click the “edit” pencil button on a given table to add or remove fields. ## ETL script [ETL scripts](https://docs.hotglue.com/docs/transformations-overview) (or transformation scripts) can be used to transform raw data from your Connector into a digestible format for your backend or Targets. ## Triggers Triggers create webhooks on your behalf to automatically run jobs when something happens in a Connector system. For example, when a new contact is added in Salesforce, a trigger can automatically run a new sync job. # Creating and Updating Source Settings Source: https://docs.hotglue.com/key-concepts/connectors/v1-sources/management Modifying Hotglue Source Settings Source settings are stored in an environment file called `availableSources.json` that you can modify via either the CLI or the Hotglue Web App. By modifiying one of the default available Source that Hotglue provides, you will be creating a forked Source. This will add a field called `isforked` to the settings. ## Modifying `availableSources.json` with the Hotglue CLI Your current list of forked Source settings can be downloaded, edited, and deployed via the [Hotglue CLI](/cli/env) ## Modifying `availableSources.json` via Hotglue environment settings You can edit your `availableSources.json` by navigating to your Environment's `Settings` > `Connectors :` ![Screenshot2025 04 25at1 44 12PM Pn](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/Screenshot2025-04-25at1.44.12PM.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=96591ac5b3dab48e6293f6fd30ffed55) And selecting Sources in the dropdown menu: ![Screenshot2025 04 25at1 44 53PM Pn](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/Screenshot2025-04-25at1.51.34PM.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=e47ab40c4614b39f5df0022c32d829e8) From there, press the Edit button for the desired Source: ![Screenshot2025 04 25at1 47 34PM Pn](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/ForkSource.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=7307e9e5c34cb12e7374f78c686826d5) > Note that `availableSources.json` is unique to each of your environments # Sources Source: https://docs.hotglue.com/key-concepts/connectors/v1-sources/overview What are Sources? # What is a Source? In V1 flows, **Sources** are third party integrations that can read data from you or your tenant's authenticated accounts For example, an e-commerce flow may include many different **Sources**, such as Shopify, Amazon Seller, and WooCommerce. ## What is an available Source? An **available Source** is a Source that you can add to your hotglue flows. You can find a complete list of the [default available Sources here](https://hotglue.com/connectors). You can also [fork and create custom sources](/cli/env) via the Hotglue CLI. ## What is a supported Source? A **supported Source** is a Source that you have configured to be available within a flow. ## What is a linked Source? A **linked Source** is a instance of Source that has been successfully connected to by a particular tenant. # Source Configuration There are four main configuration options for Hotglue Sources: 1. Credentials 2. Field maps 3. ETL scripts 4. Triggers ## Credentials Sources generally use one of two types of authorization: APIs and OAuth. Before enabling an OAuth Source, you must obtain and set up OAuth credentials. 1. Your **Client ID** and **Client Secret** will be found in your company or developer account for that Source. 2. Scope is used for some OAuth applications to define the data you will be reading or writing. This will prompt tenants to confirm the data permissions you are requesting. ![](https://files.readme.io/3b50c42-Hotglue-Oauth-API-Credentials.png) ## Field maps Field maps allow you to choose what data hotglue will pull in a sync job. **The field map** displays a list of **tables** that can be turned on or off. Within each table, **the field editor** displays a list of **fields** that can be pulled or ignored. To modify a field map for a Source, navigate to your chosen flow, click the "Source" tab, then select a Source to configure it. ![](https://files.readme.io/26fbbb6-Screen_Shot_2022-11-30_at_12.28.07_PM.png) Under configuration, click “customize field map.” From here, you can toggle **tables** on or off by clicking them. ![](https://files.readme.io/6998ef5-Screen_Shot_2022-11-30_at_12.27.32_PM.png) Click the “edit” pencil button on a given table to add or remove fields. ## ETL script [ETL scripts](https://docs.hotglue.com/docs/transformations-overview) (or transformation scripts) can be used to transform raw data from your Source into a digestible format for your backend or Targets. ## Triggers Triggers create webhooks on your behalf to automatically run jobs when something happens in a Source system. For example, when a new contact is added in Salesforce, a trigger can automatically run a new sync job. # Source Settings Source: https://docs.hotglue.com/key-concepts/connectors/v1-sources/settings Modifying Hotglue Source Settings # What are Source Settings? Source settings determine: * How a Source appears to your tenants * How you and your tenants authenticate to the Source * How Hotglue will run this Source ## Example Source Settings ```json theme={null} { "tap": "facebook", "tags": [ "ads" ], "icon": "https://s3.amazonaws.com/cdn.hotglue.xyz/images/logos/facebook_ads.svg", "domain": "facebook.com/business/ads", "label": "Facebook Ads", "validation_supported":true, "tap_url": "https://www.facebook.com/v12.0/dialog/oauth?scope=ads_management%20ads_read", "auth_url": "https://graph.facebook.com/v12.0/oauth/access_token", "type": "oauth", "connect_ui_params": { "account_id": { "label": "Account ID", "description": "Your Facebook Ads account id." } }, "connector_props": { "singer_sdk": true } } ``` ## Understanding the Source Fields ### `tap` The `tap` field is a unique identifier for the source. It is used internally to reference the source and should be unique across all sources. ### `label` The `label` field is a human-readable name for the source. This is the name that will be displayed in the user interface. ### `icon` The `icon` field is a URL to an image that represents the source. This icon will be displayed in the user interface alongside the source's label. ### `tags` The `tags` field is an array of strings that categorize the source. These tags can be used to filter and search for sources. ### `domain` The `domain` field specifies the primary domain associated with the source. This is typically the domain of the service the source integrates with. ### `type` The `type` field specifies the authentication method used by the source. Accepted values are `oauth` and `api` ### `isForked` The `isForked` field indicates whether this source has been modified from the default hotglue source settings. ### `validation_supported` The `validation_supported` field (boolean) indicates whether the connector validates a tenant’s credentials during account linking. ### `install_uri` The `install_uri` field can be used to overwrite the default git repo that the Tap will be installed from: ``` "install_uri": "git+https://github.com/your-org/tap-googleads.git@v1.2.4" ``` You can also override the `install_uri` for particular tenants by instead using: ``` "install_uri": { "env": "git+..." // Default install URI, "tenant": { "TENANT_ID": "git+..." // Install URI for particular tenant } } ``` ### `is_private_repo` The `is_private_repo` field tells hotglue to use authenticated access when installing your Tap via the [Hotglue GitHub App](/environment-settings/github-app). See [Private Repositories](/environment-settings/job-settings#private-repositories) for details. ```json theme={null} { "install_uri": "git+https://github.com/your-org/tap-googleads.git@v1.2.4", "is_private_repo": true } ``` ### `formattable_fields` The `formattable_fields` flag allows you to set a list of config flags that can be used as variables for your auth URLs. ```json theme={null} "formattable_fields": ["shop", "tenant_id"] ``` For example, if you set: ```json theme={null} "auth_url": "https://{shop}.shopify.com/token" ``` And the tenant has config: ```json theme={null} { ... "shop": "usa", ... } ``` then hotglue will use the following `auth_url` when completing the OAuth flow: ``` https://usa.shopify.com/token ``` All fields specified in the `connect_ui_params` are used as `formattable_fields` by default. ### `version` The `version` field allows you to add a chip to the Widget UI that specifies the source version. ```json theme={null} "version": "v2" ``` ![Versioning chips example](https://mintlify.s3.us-west-1.amazonaws.com/hotglue/key-concepts/connectors/v1-sources/images/versioning%20chips.png) Version chips displayed on the source card ### `tap_url` The `tap_url` field specifies the OAuth authorization URL used to initiate the authentication flow for this source. This is the URL the tenant is redirected to when connecting the source. ```json theme={null} "tap_url": "https://app.example.com/oauth/authorize?response_type=code" ``` ### `auth_url` The `auth_url` field specifies the OAuth token exchange URL used to obtain access tokens after the tenant has authorized the source. ```json theme={null} "auth_url": "https://app.example.com/oauth/token" ``` ### `revoke_url` The `revoke_url` field specifies the URL called to revoke OAuth tokens when a tenant disconnects the source. ```json theme={null} "revoke_url": "https://app.example.com/oauth/revoke" ``` ### `dynamic_urls` The `dynamic_urls` field allows the source to construct URLs dynamically at runtime using tenant-specific config values. When set to `true`, placeholders in `tap_url` and `auth_url` are replaced with values from the tenant's config. For example, Amazon Advertising uses a region-specific URL selected by the tenant: ```json theme={null} "tap_url": "{uri}/ap/oa?response_type=code&scope=advertising::campaign_management", "auth_url": "{uri}/auth/o2/token", "dynamic_urls": true, "connect_ui_params": { "uri": { "label": "Amazon Ads Region", "description": "The region of the Amazon Ads account to connect", "type": "select", "options": [ { "name": "North America (NA)", "value": "https://www.amazon.com" }, { "name": "Europe (EU)", "value": "https://www.amazon.co.uk" } ] } } ``` When a tenant selects `EU`, hotglue replaces `{uri}` with `https://www.amazon.co.uk` in the tap and auth URLs automatically. ### `flowType` The `flowType` field specifies how the source can be used across flows. When set to `all`, the source can be used in both tap and target flows. ```json theme={null} "flowType": "all" ``` ### `no_fieldmap` The `no_fieldmap` field disables field mapping for this source. ```json theme={null} "no_fieldmap": true ``` ### `disabled` The `disabled` field marks this source as disabled and unavailable for use. ```json theme={null} "disabled": true ``` ### `connector_repo` The `connector_repo` field specifies the git repository URL for a hotglue-maintained tap. This field only works with hotglue-maintained repositories. ```json theme={null} "connector_repo": "git+https://github.com/hotgluexyz/tap-example.git" ``` ### `connector_tag` The `connector_tag` field specifies the version tag of a hotglue-maintained tap repository to install. This field only works with hotglue-maintained repositories. ```json theme={null} "connector_tag": "^v1.0.0" ``` ### `connector_type` The `connector_type` field specifies the tap runtime type. ```json theme={null} "connector_type": "airbyte" ``` ### `external_repo_url` The `external_repo_url` field specifies the URL to the external repository for airbyte-sourced taps. ```json theme={null} "external_repo_url": "https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-example" ``` ### `unified_version` The `unified_version` field specifies the unified schema version used by this source. ```json theme={null} "unified_version": "v2" ``` ### `basic_client_credentials` The `basic_client_credentials` field uses HTTP Basic Auth for client credentials instead of standard OAuth. ```json theme={null} "basic_client_credentials": true ``` ### `oauth_settings` The `oauth_settings` field contains advanced OAuth configuration for the source. The following sub-fields are supported: | Field | Type | Description | | - | - | - | | `use_pkce_verifier` | boolean | Enables PKCE (Proof Key for Code Exchange) for enhanced OAuth security | | `use_basic_auth` | boolean | Sends client credentials using HTTP Basic Auth during token exchange | | `use_json_payload` | boolean | Sends the token request as a JSON payload instead of form-encoded data | | `no_code_param` | boolean | Omits the code parameter from the token request for non-standard OAuth flows | | `encode_state` | boolean | Encodes the OAuth state parameter before sending | ```json theme={null} "oauth_settings": { "use_pkce_verifier": true } ``` ### `connect_ui_params` The `connect_ui_params` field defines the fields shown to tenants in the connection UI. Each field key maps to a parameter object that supports the following properties: | Property | Type | Description | | - | - | - | | `label` | string | Human-readable label shown to the tenant for this field | | `helperText` | string | Helper text displayed below the field in Widget v3. Supports [safe HTML](/widget-v3/reference/helperText) and takes precedence over `description` | | `description` | string | Helper text displayed below the field. In Widget v3, supports [safe HTML](/widget-v3/reference/helperText) when `helperText` is not set | | `type` | string | Input type for the field. Accepted values: `password`, `boolean`, `select`, `number`, `list`, `multiline`. Defaults to text if not specified | | `required` | boolean | Whether this field is required for the tenant to connect. Defaults to `true` if not specified | | `adornment` | object | Adds prefix or suffix text around the input field | | `adornment.start` | string | Text displayed before the input field (e.g. `https://`) | | `adornment.end` | string | Text displayed after the input field (e.g. `.myshopify.com`) | | `options` | array | Used when `type` is `select`. Defines the list of options the tenant can choose from | | `options[].name` | string | Display name for the select option | | `options[].value` | string | Value submitted when this option is selected | | `params` | object | Used when `type` is `list`. Defines the sub-fields for each item in the list | The following examples show fields using different property combinations: ```json theme={null} "connect_ui_params": { "shop": { "label": "Shop", "description": "Your shop name", "adornment": { "start": "https://", "end": ".myshopify.com" } }, "region": { "label": "Region", "type": "select", "options": [ { "name": "North America", "value": "https://www.amazon.com" }, { "name": "Europe", "value": "https://www.amazon.co.uk" } ] }, "bulk": { "label": "Bulk", "type": "boolean", "required": false }, "api_key": { "label": "API Key", "description": "Your API Key", "type": "password" } } ``` #### Rich helper text in Widget v3 Widget v3 renders `helperText`, or `description` when `helperText` is absent, beneath the field. Use HTML for setup links and short formatted guidance. Allowed tags, Connect Params header text, and examples are documented in [helperText](/widget-v3/reference/helperText). ```json theme={null} "api_key": { "label": "API key", "helperText": "Where to find your API key", "type": "password" } ``` ### `connector_props` The `connector_props` field contains additional configuration properties for the tap. The following sub-fields are supported: | Field | Type | Description | | - | - | - | | `singer_sdk` | boolean | Indicates this tap is built using the Singer SDK | | `static_data` | boolean | Indicates this tap handles arbitrary file-based data sources such as file storage, Google Drive, or blob storage | | `validation_disabled` | boolean | Disables credential validation for this tap during account linking | | `tap_driver_name` | string | Overrides the default driver name used to run the connector. Use this when the driver name differs from the connector `id` | ```json theme={null} "connector_props": { "singer_sdk": true, "tap_driver_name": "example" } ``` ### `config` The `config` block defines default configuration values that are automatically applied to every new tenant connecting to this source. Tenants inherit these values without needing to configure them manually. The only universal config field supported across all sources is `start_date`. All other config fields are source-specific — refer to the individual source's documentation for the full list of supported fields. | Field | Type | Description | | - | - | - | | `start_date` | string | Default start date for data sync in ISO 8601 format | ```json theme={null} "config": { "start_date": "2000-01-01T00:00:00.000Z" } ``` # Creating and Updating Target Settings Source: https://docs.hotglue.com/key-concepts/connectors/v1-targets/management Modifying Hotglue Target Settings Target settings are stored in an environment file called `availableTargets.json` that you can modify via either the CLI or the Hotglue Web App. By modifiying one of the default available Targets that Hotglue provides, you will be creating a forked Target. This will add a field called `isforked` to the settings. ## Modifying `availableTargets.json` with the Hotglue CLI Your current list of forked target settings can be downloaded, edited, and deployed via the [Hotglue CLI](/cli/env) ## Modifying `availableTargets.json` via Hotglue environment settings You can edit your `availableTargets.json` by navigating to your Environment's `Settings` > `Connectors :` ![Screenshot2025 04 25at1 44 12PM Pn](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/Screenshot2025-04-25at1.44.12PM.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=96591ac5b3dab48e6293f6fd30ffed55) And selecting `Targets` in the dropdown menu: ![Screenshot2025 04 25at1 44 53PM Pn](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/Screenshot2025-04-25at1.51.59PM.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=b62149629d5fc167b0528e305125c90d) From there, press the `Edit` button for the desired Target: ![Screenshot2025 04 25at1 47 34PM Pn](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/ForkTarget.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=cf50c4389569681bd139bef85199ccd1) > Note that `availableTargets.json` is unique to each of your environments # Targets Source: https://docs.hotglue.com/key-concepts/connectors/v1-targets/overview What are Targets? # What is a Target? In V1 flows, **Targets** are third party integrations that allow you to write data to you or your tenant's authenticated accounts. For example, a typical flow might see you write your tenant's data to your own database using a [Postgres](/connectors/postgres) or [BigQuery](/connectors/bigquery) Target. ## What is an available Target? An **available Target** is a Target that you can add to your hotglue flows. You can [fork and create custom Targets](/cli/env) via the hotglue CLI. ## What is a supported Target? A **supported Target** is a Target that you have configured to be available within a flow. ## What is a linked Target? A **linked Target** is an instance of Target that has been successfully connected to by a particular tenant (most often the default tenant). # Target Settings Source: https://docs.hotglue.com/key-concepts/connectors/v1-targets/settings Modifying Hotglue Target Settings # What are Target Settings? Target settings determine: * How a Target appears to your tenants * How you and your tenants authenticate to the Target * The underlying taps and targets that your Target uses ## Example Target Settings ```json theme={null} { "target": "postgres-beta", "flowType": "all", "domain": "postgresql.org", "label": "PostgreSQL", "version": "v2", "type": "api", "icon": "https://s3.amazonaws.com/cdn.hotglue.xyz/images/logos/postgres.svg", "validation_supported": true, "connect_ui_params": { "host": { "label": "Host Name", "description": "Your PostgreSQL server host" }, "port": { "label": "Port", "description": "Your PostgreSQL server port" }, "dbname": { "label": "Database", "description": "Your PostgreSQL database name" }, "user": { "label": "User", "description": "Your PostgreSQL user" }, "password": { "label": "Password", "description": "Your PostgreSQL password", "type": "password" }, "default_target_schema": { "label": "Schema", "description": "Your PostgreSQL schema (ie. public)" }, }, "connector_props": { "singer_sdk": true } } ``` ## Understanding the Target Fields ### `target` The `target` field is a unique identifier for the target. It is used internally to reference the target and should be unique across all targets. ### `label` The `label` field is a human-readable name for the target. This is the name that will be displayed in the user interface. ### `icon` The `icon` field is a URL to an image that represents the target. This icon will be displayed in the user interface alongside the target's label. ### `tags` The `tags` field is an array of strings that categorize the target. These tags can be used to filter and search for targets. ### `domain` The `domain` field specifies the primary domain associated with the target. This is typically the domain of the service the target integrates with. ### `type` The `type` field specifies the authentication method used by the target. Accepted values are `oauth`, `api`, and `iam`. ### `isForked` The `isForked` field indicates whether this target has been modified from the default hotglue target settings. ### `install_uri` The `install_uri` field can be used to overwrite the default git repo that the target will be installed from: ``` "install_uri": "git+https://github.com/your-org/target-bigquery.git@v1.2.4" ``` You can also override the `install_uri` for particular tenants by instead using: ``` "install_uri": { "env": "git+..." // Default install URI, "tenant": { "TENANT_ID": "git+..." // Install URI for particular tenant } } ``` ### `is_private_repo` The `is_private_repo` field tells hotglue to use authenticated access when installing your Tap via the [Hotglue GitHub App](/environment-settings/github-app). See [Private Repositories](/environment-settings/job-settings#private-repositories) for details. ```json theme={null} { "install_uri": "git+https://github.com/your-org/target-googleads.git@v1.2.4", "is_private_repo": true } ``` ### `formattable_fields` The `formattable_fields` flag allows you to set a list of config flags that can be used as variables for your auth URLs. ```json theme={null} "formattable_fields": ["shop", "tenant_id"] ``` For example, if you set: ```json theme={null} "auth_url": "https://{shop}.shopify.com/token" ``` And the tenant has config: ```json theme={null} { ... "shop": "usa", ... } ``` then hotglue will use the following `auth_url` when completing the OAuth flow: ``` https://usa.shopify.com/token ``` All fields specified in the `connect_ui_params` are used as `formattable_fields` by default. ### `version` The `version` field adds a version label chip to the target card in the UI. This helps tenants identify which version of the target they are using. ```json theme={null} "version": "v2" ``` ### `validation_supported` The `validation_supported` field (boolean) indicates whether the target validates a tenant's credentials during account linking. ```json theme={null} "validation_supported": true ``` ### `flowType` The flowType field controls whether the connector can be used in both source and target flows. When set to all, the connector becomes available in both source and target flows. ```json theme={null} "flowType": "all" ``` ### `target_url` The `target_url` field specifies the OAuth authorization URL used to initiate the authentication flow for this target. This is the URL the tenant is redirected to when connecting the target. ```json theme={null} "target_url": "https://app.example.com/oauth/authorize?response_type=code" ``` ### `auth_url` The `auth_url` field specifies the OAuth token exchange URL used to obtain access tokens after the tenant has authorized the target. ```json theme={null} "auth_url": "https://app.example.com/oauth/token" ``` ### `revoke_url` The `revoke_url` field specifies the URL called to revoke OAuth tokens when a tenant disconnects the target. ```json theme={null} "revoke_url": "https://app.example.com/oauth/revoke" ``` ### `dynamic_urls` The `dynamic_urls` field allows the target to construct URLs dynamically at runtime using tenant-specific config values. When set to `true`, placeholders in `target_url` and `auth_url` are replaced with values from the tenant's config. For example, Databricks uses a host-specific URL entered by the tenant: ```json theme={null} "target_url": "https://{host}/oidc/v1/authorize?response_type=code&scope=sql%20offline_access", "auth_url": "https://{host}/oidc/v1/token", "dynamic_urls": true, "connect_ui_params": { "host": { "label": "Host", "description": "Databricks SQL Warehouse Host" } } ``` ### `basic_client_credentials` The `basic_client_credentials` field uses HTTP Basic Auth for client credentials instead of standard OAuth. ```json theme={null} "basic_client_credentials": true ``` ### `connector_repo` The `connector_repo` field specifies the git repository URL for a hotglue-maintained target. This field only works with hotglue-maintained repositories. ```json theme={null} "connector_repo": "git+https://github.com/hotgluexyz/target-example.git" ``` ### `connector_tag` The `connector_tag` field specifies the version tag of a hotglue-maintained target repository to install. This field only works with hotglue-maintained repositories. ```json theme={null} "connector_tag": "^v1.0.0" ``` ### `oauth_settings` The `oauth_settings` field contains advanced OAuth configuration for the target. The following sub-fields are supported: | Field | Type | Description | | - | - | - | | `use_pkce_verifier` | boolean | Enables PKCE (Proof Key for Code Exchange) for enhanced OAuth security | | `use_basic_auth` | boolean | Sends client credentials using HTTP Basic Auth during token exchange | | `use_json_payload` | boolean | Sends the token request as a JSON payload instead of form-encoded data | | `encode_state` | boolean | Encodes the OAuth state parameter before sending | ```json theme={null} "oauth_settings": { "use_pkce_verifier": true } ``` ### `connect_ui_params` The `connect_ui_params` field defines the fields shown to tenants in the connection UI. Each field key maps to a parameter object that supports the following properties: | Property | Type | Description | | - | - | - | | `label` | string | Human-readable label shown to the tenant for this field | | `helperText` | string | Helper text displayed below the field in Widget v3. Supports [safe HTML](/widget-v3/reference/helperText) and takes precedence over `description` | | `description` | string | Helper text displayed below the field. In Widget v3, supports [safe HTML](/widget-v3/reference/helperText) when `helperText` is not set | | `type` | string | Input type for the field. Accepted values: `password`, `boolean`, `select`, `number`, `list`, `multiline`. Defaults to text if not specified | | `required` | boolean | Whether this field is required for the tenant to connect. Defaults to `true` if not specified | | `adornment` | object | Adds prefix or suffix text around the input field | | `adornment.start` | string | Text displayed before the input field (e.g. `https://`) | | `adornment.end` | string | Text displayed after the input field (e.g. `.myshopify.com`) | | `options` | array | Used when `type` is `select`. Defines the list of options the tenant can choose from | | `options[].name` | string | Display name for the select option | | `options[].value` | string | Value submitted when this option is selected | | `params` | object | Used when `type` is `list`. Defines the sub-fields for each item in the list | The following examples show fields using different property combinations: ```json theme={null} "connect_ui_params": { "host": { "label": "Host Name", "description": "Your server host" }, "password": { "label": "Password", "description": "Your password", "type": "password" }, "region": { "label": "Region", "type": "select", "options": [ { "name": "US East", "value": "us-east-1" }, { "name": "EU West", "value": "eu-west-1" } ] }, "ssl": { "label": "Use SSL", "type": "boolean", "required": false } } ``` #### Rich helper text in Widget v3 Widget v3 renders `helperText`, or `description` when `helperText` is absent, beneath the field. Use HTML for setup links and short formatted guidance. Allowed tags, Connect Params header text, and examples are documented in [helperText](/widget-v3/reference/helperText). ```json theme={null} "api_key": { "label": "API key", "helperText": "Where to find your API key", "type": "password" } ``` ### `connector_props` The `connector_props` field contains additional configuration properties for the target. The following sub-fields are supported: | Field | Type | Description | | - | - | - | | `singer_sdk` | boolean | Indicates this target is built using the Singer SDK | | `static_data` | boolean | Indicates this target handles arbitrary file-based data sources such as file storage, Google Drive, or blob storage | | `tap_driver_name` | string | Overrides the default driver name used to run the connector. Use this when the driver name differs from the connector `id` | ```json theme={null} "connector_props": { "singer_sdk": true, "tap_driver_name": "example" } ``` ### `config` The `config` block defines default configuration values that are automatically applied to every new tenant connecting to this target. Tenants inherit these values without needing to configure them manually. The only universal config field supported across all targets is `start_date`. All other config fields are target-specific — refer to the individual target's documentation for the full list of supported fields. | Field | Type | Description | | - | - | - | | `start_date` | string | Default start date for data sync in ISO 8601 format | ```json theme={null} "config": { "start_date": "2000-01-01T00:00:00.000Z" } ``` # Creating and Updating Connector Settings Source: https://docs.hotglue.com/key-concepts/connectors/v2-connectors/management Modifying Hotglue Connector Settings Connector settings are stored in an environment file called `availableConnectors.json` that you can modify via either the CLI or the Hotglue Web App. By modifiying one of the default available Connectors that Hotglue provides, you will be creating a forked connector. This will add a field called `isforked` to the settings. ## Modifying `availableConnectors.json` with the Hotglue CLI Your current list of forked connector settings can be downloaded, edited, and deployed via the [Hotglue CLI](/cli/env) ## Modifying `availableConnectors.json` via Hotglue environment settings You can edit your `availableConnectors.json` by navigating to your Environment's `Settings` > `Connectors :` ![Screenshot2025 04 25at1 44 12PM Pn](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/Screenshot2025-04-25at1.44.12PM.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=96591ac5b3dab48e6293f6fd30ffed55) And selecting Connectors in the dropdown menu: ![Screenshot2025 04 25at1 44 53PM Pn](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/Screenshot2025-04-25at1.44.53PM.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=6ea0cc8d4f0ef21df6e6e2dbde1bdbf6) From there, press the Edit button for the desired Connector: ![Screenshot2025 04 25at1 47 34PM Pn](https://mintcdn.com/hotglue/5Ve6qyQIr-eWU9BP/images/Screenshot2025-04-25at1.47.34PM.png?fit=max\&auto=format\&n=5Ve6qyQIr-eWU9BP\&q=85\&s=aa96af4d5547c229e2204cadee17b707) > Note that `availableConnectors.json` is unique to each of your environments # Connector Settings Source: https://docs.hotglue.com/key-concepts/connectors/v2-connectors/settings Modifying Hotglue Connector Settings # What are Connector Settings? Connector settings determine: * How a connector appears to your tenants * How you and your tenants authenticate to the connector * The underling taps and targets that your connector uses ## Example Connector Settings ```json theme={null} { "id": "shopify", "label": "Shopify", "type": "api", "tags": [ "ecommerce", "featured" ], "icon": "https://s3.amazonaws.com/cdn.hotglue.xyz/images/logos/shopify.svg", "domain": "shopify.com", "isConnector": true, "isSource": false, "isTarget": false, "read_connector": { "id": "shopify" }, "write_connector": { "id": "shopify-v2", "install_uri": "git+https://gitlab.com/hotglue/target-shopify-v2.git@bump-to-use-new-target-sdk" }, "connect_ui_params": { "api_key": { "label": "API Password", "description": "Shopify API Password", "type": "password" }, "api_key_id": { "label": "API Key", "description": "Shopify API Key", "type": "password", "required": false }, "shop": { "label": "Shop", "description": "Shopify shop name (ie. the value test_shop in the string https://test_shop.myshopify.com)", "adornment": { "start": "https://", "end": ".myshopify.com" } }, "bulk": { "type": "boolean", "label": "Bulk", "required": false } }, "options": { "auto_support": true, "has_triggers": true, "validation_supported": true, "available_triggers": [ { "id": "orders/create", "name": "Created order", "description": "Triggered when a new sale order is created" }, { "id": "orders/delete", "name": "Deleted order", "description": "Triggered when a sale order is deleted" }, { "id": "products/create", "name": "Created product", "description": "Triggered when a new product is created" }, { "id": "products/delete", "name": "Deleted product", "description": "Triggered when a product is deleted" } ], "config": { "start_date": "2015-01-01T00:00:00.000Z", "date_window_size": 365 }, "schemaTables": [ "SalesOrders" ], "hg_schema": "ecommerce" }, "isForked": true } ``` ## Understanding the Connector Fields ### `id` The `id` field is a unique identifier for the connector. It is used internally to reference the connector and should be unique across all connectors. ### `label` The `label` field is a human-readable name for the connector. This is the name that will be displayed in the user interface. ### `icon` The `icon` field is a URL to an image that represents the connector. This icon will be displayed in the user interface alongside the connector's label. ### `tags` The `tags` field is an array of strings that categorize the connector. These tags can be used to filter and search for connectors. ### `domain` The `domain` field specifies the primary domain associated with the connector. This is typically the domain of the service the connector integrates with. ### `type` The `type` field specifies the authentication method used by the connector. Accepted values are `oauth` and `api` ### `read_connector` and `write_connector` These fields specify the Git repositories of the tap and target respectively. The following sub-fields are supported inside `read_connector` and `write_connector`: | Field | Type | Description | | - | - | - | | `id` | string | Unique identifier for the tap or target | | `install_uri` | string | Custom git install URI. Overrides the default installation source | | `connector_repo` | string | Full git repository URL for the tap or target. Only works with hotglue-maintained repositories | | `connector_tag` | string | Version tag of the repository to install. Only works with hotglue-maintained repositories | | `singer_sdk` | boolean | Indicates this tap or target is built using the Singer SDK | | `is_private_repo` | boolean | Uses authenticated access to install from a private repository. GitHub repositories use the [Hotglue GitHub App](/environment-settings/github-app), while GitLab repositories continue to use an existing environment Git access token. See [Private Repositories](/environment-settings/job-settings#private-repositories) for details. | | `static_data` | boolean | Indicates this tap serves static pre-loaded data rather than live API data | | `validation_disabled` | boolean | Disables credential validation for this tap during account linking | | `tap_driver_name` | string | Overrides the default driver name used to run the connector. Use this when the driver name differs from the connector `id` | If the connector uses a custom branch of a git repo, you can set a custom install uri: ```json theme={null} "write_connector": { "id": "shopify-v2", "install_uri": "git+https://gitlab.com/hotglue/target-shopify-v2.git@bump-to-use-new-target-sdk" }, ``` The `is_private_repo` field tells hotglue to use authenticated access when installing your Tap via the [Hotglue GitHub App](/environment-settings/github-app). See [Private Repositories](/environment-settings/job-settings#private-repositories) for details. ```json theme={null} { "write_connector": { "id": "shopify-v2", "install_uri": "git+https://gitlab.com/hotglue/target-shopify-v2.git@bump-to-use-new-target-sdk", "is_private_repo": true } } ``` For a private GitHub repository, make sure the Hotglue GitHub App installation includes the repository: ```json theme={null} { "read_connector": { "id": "private-source", "install_uri": "git+https://github.com/your-org/private-source.git@v1.0.0", "is_private_repo": true } } ``` If the connector uses a tagged release of a repository, you can specify that connector tag: ```json theme={null} "connector_repo": "git+https://github.com/hotgluexyz/target-redshift.git", "connector_tag": "^v1.6.1", "singer_sdk": true ``` ### `isForked` The `isForked` field indicates whether this connector has been modified from the default Hotglue connector settings. ### `formattable_fields` The `formattable_fields` flag allows you to set a list of config flags that can be used as variables for your auth URLs. ```json theme={null} "formattable_fields": ["shop", "tenant_id"] ``` For example, if you set: ```json theme={null} "auth_url": "https://{shop}.shopify.com/token" ``` And the tenant has config: ```json theme={null} { ... "shop": "usa", ... } ``` then hotglue will use the following `auth_url` when completing the OAuth flow: ``` https://usa.shopify.com/token ``` All fields specified in the `connect_ui_params` are used as `formattable_fields` by default. ### `isConnector` The `isConnector` field marks whether this entry is a bi-directional connector. ```json theme={null} "isConnector": true, "isSource": false, "isTarget": false ``` ### `isSource` The `isSource` field marks whether this connector can act as the source in a V2 bidirectional flow. ### `isTarget` The `isTarget` field marks whether this connector can act as the target in a V2 bidirectional flow. ### `version` The `version` field adds a version label chip to the connector card in the UI. This helps tenants identify which version of the connector they are using. ```json theme={null} "version": "v2" ``` ### `auth_url` The `auth_url` field specifies the OAuth authorization URL used to initiate the authentication flow for this connector. ```json theme={null} "auth_url": "https://app.example.com/oauth/authorize" ``` ### `token_url` The `token_url` field specifies the OAuth token exchange URL used to obtain access tokens after the tenant has authorized the connector. ```json theme={null} "token_url": "https://app.example.com/oauth/token" ``` ### `revoke_url` The `revoke_url` field specifies the URL called to revoke OAuth tokens when a tenant disconnects the connector. ```json theme={null} "revoke_url": "https://app.example.com/oauth/revoke" ``` ### `dynamic_urls` The `dynamic_urls` field allows the connector to construct URLs dynamically at runtime using tenant-specific config values. When set to `true`, placeholders in `auth_url` and `token_url` are replaced with values from the tenant's config. For example, Zoho uses a region-specific URL selected by the tenant: ```json theme={null} "auth_url": "{uri}/oauth/v2/auth?response_type=code&scope=ZohoInventory.FullAccess.all", "token_url": "{uri}/oauth/v2/token", "dynamic_urls": true, "connect_ui_params": { "uri": { "label": "Zoho Region", "type": "select", "options": [ { "name": "US", "value": "https://accounts.zoho.com" }, { "name": "EU", "value": "https://accounts.zoho.eu" } ] } } ``` When a tenant selects `EU`, hotglue replaces `{uri}` with `https://accounts.zoho.eu` in the auth and token URLs automatically. ### `connector_repo` The `connector_repo` field specifies the git repository URL for a hotglue-maintained connector. This field only works with hotglue-maintained repositories. ```json theme={null} "connector_repo": "git+https://github.com/hotgluexyz/tap-sharepoint.git" ``` ### `connector_tag` The `connector_tag` field specifies the version tag of a hotglue-maintained connector repository to install. This field only works with hotglue-maintained repositories. ```json theme={null} "connector_tag": "^v1.0.0" ``` ### `oauth_settings` The `oauth_settings` field contains advanced OAuth configuration for the connector. The following sub-fields are supported: | Field | Type | Description | | - | - | - | | `use_pkce_verifier` | boolean | Enables PKCE (Proof Key for Code Exchange) for enhanced OAuth security | | `use_basic_auth` | boolean | Sends client credentials using HTTP Basic Auth during token exchange | | `use_json_payload` | boolean | Sends the token request as a JSON payload instead of form-encoded data | | `no_code_param` | boolean | Omits the code parameter from the token request for non-standard OAuth flows | | `encode_state` | boolean | Encodes the OAuth state parameter before sending | ```json theme={null} "oauth_settings": { "use_pkce_verifier": true } ``` ### `connect_ui_params` The `connect_ui_params` field defines the fields shown to tenants in the connection UI. Each field key maps to a parameter object that supports the following properties: | Property | Type | Description | | - | - | - | | `label` | string | Human-readable label shown to the tenant for this field | | `helperText` | string | Helper text displayed below the field in Widget v3. Supports [safe HTML](/widget-v3/reference/helperText) and takes precedence over `description` | | `description` | string | Helper text displayed below the field. In Widget v3, supports [safe HTML](/widget-v3/reference/helperText) when `helperText` is not set | | `type` | string | Input type for the field. Accepted values: `password`, `boolean`, `select`, `number`, `list`, `multiline`. Defaults to text if not specified | | `required` | boolean | Whether this field is required for the tenant to connect. Defaults to `true` if not specified | | `adornment` | object | Adds prefix or suffix text around the input field | | `adornment.start` | string | Text displayed before the input field (e.g. `https://`) | | `adornment.end` | string | Text displayed after the input field (e.g. `.myshopify.com`) | | `options` | array | Used when `type` is `select`. Defines the list of options the tenant can choose from | | `options[].name` | string | Display name for the select option | | `options[].value` | string | Value submitted when this option is selected | | `params` | object | Used when `type` is `list`. Defines the sub-fields for each item in the list | The following examples show fields using different property combinations: ```json theme={null} "connect_ui_params": { "shop": { "label": "Shop", "description": "Your Shopify shop name", "adornment": { "start": "https://", "end": ".myshopify.com" } }, "region": { "label": "Region", "type": "select", "options": [ { "name": "North America", "value": "https://www.amazon.com" }, { "name": "Europe", "value": "https://www.amazon.co.uk" } ] }, "bulk": { "label": "Bulk", "type": "boolean", "required": false }, "api_key": { "label": "API Key", "description": "Your API Key", "type": "password" } } ``` #### Rich helper text in Widget v3 Widget v3 renders `helperText`, or `description` when `helperText` is absent, beneath the field. Use HTML for setup links and short formatted guidance. Allowed tags, Connect Params header text, and examples are documented in [helperText](/widget-v3/reference/helperText). ```json theme={null} "api_key": { "label": "API key", "helperText": "Where to find your API key", "type": "password" } ``` ### `options` The `options` field is a container for advanced connector configuration. The following sub-fields are supported: | Field | Type | Description | | - | - | - | | `validation_supported` | boolean | Indicates whether the connector validates tenant credentials during account linking | | `no_fieldmap` | boolean | Disables field mapping for this connector | | `no_refresh` | boolean | Disables automatic token refresh for this connector | | `force_redirect` | boolean | Forces the OAuth redirect flow even when not strictly required | | `autogen_fieldmap` | boolean | Automatically generates a field map for this connector | | `disabled` | boolean | Marks this connector as disabled and unavailable for use | | `dynamic_urls` | boolean | Enables dynamic URL construction using tenant config values | | `basic_client_credentials` | boolean | Uses HTTP Basic Auth for client credentials instead of standard OAuth | | `unified_version` | string | Specifies the unified schema version used by this connector (e.g. `v2`) | | `connector_type` | string | Specifies the connector runtime type (e.g. `airbyte`) | | `revoke_url` | string | URL to revoke OAuth tokens when a tenant disconnects. Used by some connectors inside `options` | | `customLoginButton` | string | Specifies a custom login button style shown in the connection UI (e.g. `google`) | | `external_repo_url` | string | URL to the external repository for airbyte-sourced connectors | | `config` | object | Defines default config values automatically applied to every new tenant. See [Default configs](#default-configs) below | ```json theme={null} "options": { "validation_supported": true, "dynamic_urls": true } ``` ### Default configs The `config` block is a sub-key of `options`. It defines default configuration values that are automatically applied to every new tenant connecting to this connector. Tenants inherit these values without needing to configure them manually. The only universal config field supported across all connectors is start\_date. All other config fields are connector-specific — refer to the individual connector's documentation for the full list of supported fields. | Field | Type | Description | | - | - | - | | `start_date` | string | Default start date for data sync in ISO 8601 format | ```json theme={null} "options": { "config": { "start_date": "2000-01-01T00:00:00.000Z" } } ``` # Environments Source: https://docs.hotglue.com/key-concepts/environments What hotglue environments are, and how to use them ## What is an environment? ![](https://files.readme.io/92b5937-hotglue-EnvironmentDashboard.png) Environment Dashboard In hotglue, we provide the ability to create segmented development, staging, and production environments to manage your integrations. When you first signup for hotglue, we automatically generate your development environment with an id with the format dev.hotglue.yourdomain.com. This is where you can start testing hotglue and developing your first integrations. The advantages of having segmented environments are: 1. to give you the flexibility to build and test new integrations without affecting your production tenants 2. when embedding hotglue you can specify the environment to use – so in your product's staging environment, you should use your staging hotglue environment 3. each environment can be configured to push data to different targets – so in your staging environment, data can go to a testing database rather than a production database ## Moving out of your development environment Once you have your integrations configured and ready to use, you should promote your configured flows to a new staging or production environment. The first step is to create a new environment. We recommend creating environments with the following ID formats: * `dev.hotglue.yourdomain.com` * `staging.hotglue.yourdomain.com` * `prod.hotglue.yourdomain.com` ![](https://files.readme.io/d370557-hotglue-CreateEnvironment.png) Create Environment Dialog From there you can copy your integration flows across environments – feel free to [reach out to hotglue support](mailto:support@hotglue.xyz) if you need help with this process. # Flows Source: https://docs.hotglue.com/key-concepts/flows What are flows? ## What is a flow? In hotglue, each "type" of integration you want to offer users is grouped into a **flow.** For example, you may want your users to import data from **Development** tools, like GitHub and GitLab, and **E-Commerce** shops, like Shopify and WooCommerce. When your users first open the hotglue widget they'll see something like the following: ![](https://files.readme.io/8a39f05-Screen_Shot_2022-06-10_at_3.50.18_PM.png) hotglue widget - flows This allows your user to select what they wish to import, and more importantly **where they want to import it from.** For example, if your user wanted to import **E-Commerce** data they may be able to import it from sources like Shopify, WooCommerce, and Magento. In the hotglue widget, this would look something like below: ![](https://files.readme.io/8faa323-Screen_Shot_2022-06-10_at_3.54.09_PM.png) hotglue widget - E-Commerce flow ## How do flows help me? Flows serve two main purposes: 1. Flows let you define **what types of integrations you want to support.** For example, for a **Development** flow you may want to support importing data from GitHub or GitLab - but that doesn't make much sense for an **E-Commerce** flow. 2. Flows make it easy for your users to keep track of their data. Users can clearly see what kinds of data your application needs, and what platforms they can connect. ![](https://files.readme.io/bcdcd85-Screen_Shot_2022-06-10_at_3.57.26_PM.png) hotglue widget - Development flow connected ## Flow types There are three types of flows that you can enable in hotglue: ## V1 - One-way flows #### Source flow This is the simplest way to use hotglue, and the default flow type when you toggle off **bidirectional flows**. With a source flow, your customer connects the `source` or `tap`, and you read data in from those linked sources into your own default target. #### Target flow This can be enabled in the **General** tab of a V1 flow. This is the inverse of a source flow, where your customer links an integration that you write data out to, but cannot read data in from. ### V2 - Bidirectional flows If you need to read and write data to the same integration, you can use a bidirectional flow to use the same connection for both. # V2 Bidirectional Flows Source: https://docs.hotglue.com/key-concepts/flows/bidirectional What are bidirectional flows? If you need to read and write data to the same integration, you can use a bidirectional flow to use the same connection for both. In a V2 flow, your tenants will link their account once, allowing you to run two types of jobs: 1. Read jobs -- Read data from their linked account 2. Write jobs -- Write data to their linked account Bidirectional flows utilize the [V2 API](/api-reference/v2/introduction) and [V2 Connectors](/key-concepts/connectors/v2-connectors/management) ## Bidirectional flow structure There are 3 types of connectors in a bidirectional flow: * The primary connector which your tenant links to * The target connector to be used in **Read** jobs * The source connector to be used in **Write** jobs ![V2 flows overview tab](https://mintcdn.com/hotglue/WfXuHr49lRpu5FgS/images/v2flowsoverview.png?fit=max\&auto=format\&n=WfXuHr49lRpu5FgS\&q=85\&s=6a66d1802f44985bb2d827dbc1939bc7) ## Examples Common uses of Bidirectional flows include: * Have tenants link their CRM: * Use **Read** jobs to sync their CRM data to your database * Use **Write** jobs to sync custom fields from your platform to their CRM * Have tenants link their own database: * Use **Read** jobs to import their data into your platform via a webhook * Use **Write** jobs to sync updates made on your platform back to their database # V1 Source Flows Source: https://docs.hotglue.com/key-concepts/flows/source What are source flows? Source flows are the simplest way to use hotglue, and the default flow type. With a source flow, your customer connects the `source` or `tap`, and you read data in from those linked sources into your own default target. Source flows utilize the [V1 API](/api-reference/v1/introduction) ## Examples Common uses of Source flows include: * Reading data from your tenants' CRM and writing to your own database * Checking for accounting data updates in your tenants' ERP, and writing the updates to your system via a webhook ## Allowing your tenants to fork a target In Source flows, data will default to being written to the target linked by the [default tenant](/key-concepts/tenants/default-tenant). However, your tenants may want to write their data to their own accounts. You have a tenant fork their own [linked target](/key-concepts/connectors/v1-targets/overview#what-is-a-linked-target) by: * Using the [linked target endpoint](/api-reference/v1/linked-targets/link-a-target) * Passing the `isTarget` option when linking via the widget * Manually creating the linked target in the hotglue admin dashboard # V1 Target Flows Source: https://docs.hotglue.com/key-concepts/flows/target What are target flows? In target flows, the tenant will link the target instead of the source, so that the data will be written to a tenants connected integration. Target flows utilize the [V1 API](/api-reference/v1/introduction) ## Examples Common uses of Target flows include: * Syncing data to your tenants' CRMs via hotglue's [job trigger endpoint](/api-reference/v1/jobs/run-job#body-state) * Exporting invoice and accounting data to your tenants' ERPs ## Creating a Target flow [https://www.loom.com/embed/e2f80634de5a48409e9cfc051eb94867?hide\_owner=true\&hide\_share=true\&hide\_title=true\&hideEmbedTopBar=true](https://www.loom.com/embed/e2f80634de5a48409e9cfc051eb94867?hide_owner=true\&hide_share=true\&hide_title=true\&hideEmbedTopBar=true) # Custom Filters Source: https://docs.hotglue.com/key-concepts/jobs/custom-filter Filter which records get synced per stream using custom filter conditions ## Overview Custom Filters let you control exactly which records get synced for a given stream. Instead of syncing all records, you can define conditions, such as filtering bills by status or vendor, so that only matching records are returned when a job runs. > [!NOTE] > > Custom Filters is a **beta feature** currently supported on **Coupa** and **NetSuite** connectors on select streams only. To enable custom filters for other connectors or streams, contact [hotglue support](mailto:hello@hotglue.xyz). ## Prerequisites To enable custom filters for a connector, add **`"capabilities": ["customFilters"]`** to the connector's root-level configuration in the available entity's JSON. ```json theme={null} { "tap": "netsuite", "label": "NetSuite", "capabilities": [ "customFilters" ] } ``` Once this is done, the **Filter source streams** option becomes visible in the Configuration tab. ![Filter Source Streams](https://mintcdn.com/hotglue/JQ0AYzVpVNPI0Iov/key-concepts/jobs/images/Custom_filter-Filter_Source_Streams.png?fit=max\&auto=format\&n=JQ0AYzVpVNPI0Iov\&q=85\&s=cfad193b3c64b27f17ecac0f56e56cde) > [!WARNING] > > This field must be added at the root level of the connector configuration, not inside `options` or `config`. ## Setting up custom filters ### Step 1: Link NetSuite Create a flow and link NetSuite as your source connector. Once linked, navigate to the **Configuration** tab of the NetSuite source. ![Netsuite Source Connector](https://mintcdn.com/hotglue/JQ0AYzVpVNPI0Iov/key-concepts/jobs/images/Custom_filter-Netsuite_Source_connector.png?fit=max\&auto=format\&n=JQ0AYzVpVNPI0Iov\&q=85\&s=9b28c2a5a934d4c6952c5003cea9c4a1) ### Step 2: Select one or more streams Click **Customize field map** and select the streams you want to sync e.g., **Bills**. Save your selection before proceeding. ![Select tables in field map](https://mintcdn.com/hotglue/JQ0AYzVpVNPI0Iov/key-concepts/jobs/images/Custom_filter-Select_tables.png?fit=max\&auto=format\&n=JQ0AYzVpVNPI0Iov\&q=85\&s=6da06d9c8a0b7f278059bc486d6f7b22) ### Step 3: Open Filter Source Streams Once streams are selected and saved, click **Filter source streams** to open the filter panel. You will see the stream or a list of the streams. Only streams that have been selected in your field map will appear here. ![Filters panel](https://mintcdn.com/hotglue/JQ0AYzVpVNPI0Iov/key-concepts/jobs/images/Custom_filter-Filters_panel.png?fit=max\&auto=format\&n=JQ0AYzVpVNPI0Iov\&q=85\&s=cf891343489ed94435c4d936dd78d005) ### Step 4: Build and Apply a filter Click on a stream e.g., **bills**, to open the filter builder. ![Filters builder](https://mintcdn.com/hotglue/JQ0AYzVpVNPI0Iov/key-concepts/jobs/images/Custom_filter-Filter_builder.png?fit=max\&auto=format\&n=JQ0AYzVpVNPI0Iov\&q=85\&s=b19d807e1962e30c50dc1c6110924a5d) In the filter builder, you can define one or more filter conditions: * **Field**: The property to filter on (e.g., Bill Vendor ID, Bill Vendor Name) * **Operator**: How to match the value: * `IN`: matches any value in a list * `EQ`: equals a single value * **Value**: The value(s) to match against To add multiple conditions, click **+ Add condition**. Use the **AND / OR** toggle between conditions to control how they combine: * **AND**: Both conditions must be true (narrows results) * **OR**: Either condition can be true (broadens results) For more complex logic, use **+ Add group** to nest conditions together. The filters below returns only bills that are Open **and** belong to vendor Golden Eagle Ventures. Once your conditions are defined, click **Apply Filters**. ![Build\_Apply\_filters](https://mintcdn.com/hotglue/JQ0AYzVpVNPI0Iov/key-concepts/jobs/images/Custom_filter-Build_Apply_filters.png?fit=max\&auto=format\&n=JQ0AYzVpVNPI0Iov\&q=85\&s=6d4f75f4174e6b145794332b84c26a9e) ### Step 5: Save the filter You will be taken back to the stream list, which will now show the number of active conditions next to the stream name (e.g., bills · 2 conditions). Click **Save Changes** and wait for the confirmation message before proceeding. ![Filter panel save changes.png](https://mintcdn.com/hotglue/JQ0AYzVpVNPI0Iov/key-concepts/jobs/images/Custom_filter_Filter_panel_save_changes.png?fit=max\&auto=format\&n=JQ0AYzVpVNPI0Iov\&q=85\&s=bc464da1f3149db90a1b935e19b7a6bf) The confirmation message will show up for the saved filters. ![Filter Successfully saved](https://mintcdn.com/hotglue/JQ0AYzVpVNPI0Iov/key-concepts/jobs/images/Custom_filter-Filter_Successfully_Saved.png?fit=max\&auto=format\&n=JQ0AYzVpVNPI0Iov\&q=85\&s=190d6bbb87388f42d4631a021fd8de58) ### Step 6: Run a job Navigate to the **Jobs** tab and run a new job with NetSuite as the source. ![Job created](https://mintcdn.com/hotglue/JQ0AYzVpVNPI0Iov/key-concepts/jobs/images/Custom_filter-Job_created.png?fit=max\&auto=format\&n=JQ0AYzVpVNPI0Iov\&q=85\&s=a3d938c63c2836aad1d029c48052b6c9) Once the job completes, the output will contain only the records that match your filter conditions. ## Notes * Filters are saved **per stream** and persist across future job runs until changed or removed. * Filters only apply to streams that have been selected in the field map. If a stream is not selected, it will not appear in the filter panel. * To clear all filters for a stream, open the filter builder and click **Clear all**. # Job Details Source: https://docs.hotglue.com/key-concepts/jobs/details The `job_details.json` object describes metadata about a job. Each job lifecycle webhook will contain corresponding job details for that stage. | Key | Description | | - | - | | `job_id` | An auto-generated unique ID to track jobs. | | `env_id` | The hotglue environment ID | | `flow_id` | The flow ID, found in the General or Settings tab of your flow | | `job_name` | An optional identifier passed when triggering jobs via API. Job names are auto-assigned when triggered by webhooks or the scheduler. | | `tenant` | The tenant ID, usually 1:1 with your internal ID for your customer | | `started_by` | Usually the same as the tenant ID | | `s3_root` | A unique path identifying the job. **The S3 root is ALWAYS unique for a given job** | | `start_time` | The UTC datetime at which the task began running | | `state` | An optional JSON object that holds webhook payloads, API write job payloads, and other data for use in targets and ETL scripts | | `tap` | The data source of the job. | | `target` | The data target of the job. | | `connector_id` | In V2 flows, the connector linked by the user. This may function as a source or a target | | `job_type` | In V2 flows, whether the job is of type `READ` or `WRITE` | | `status` | The [lifecycle status](https://docs.hotglue.com/docs/jobs-lifecycle) of the job | | `scheduled_job` | A boolean value, denoting whether or not the job was kicked off by hotglue's scheduler. | | `sync_type` | Jobs triggered by linking automations are marked as `auto_sync`. Other jobs that run without a `state.json` are denoted as `full_sync`. All other jobs are marked `incremental_sync`. | | `override_start_date` | An optional datetime passed to the job that overrides the start\_date and state.json. This date is not persisted outside of a given job | | `message` | The error or success message from a given job. For failing jobs, this will be hotglue's best prediction of the cause of the failure, although it may not always provide full context. | | `task_id` | This is an internal hotglue ID used for debugging. | | `task_type` | Denotes whether the job runs on hotglue's `STANDARD`, `LOW_LATENCY`, or `STATIC_IP` infrastructure. | | `task_definition` | An object with metrics defining the memory, CPU, and server location that a job runs on | | `last_updated` | The last registered job event, in UTC. For completed jobs, this will be the time of completion. | | `metrics` | - `recordCount` shows the number of records fetched for each stream - `exportSummary` is displayed when using a target built on hotglue's SDK. This shows each stream that was written to a hotglue target, with the number of records in each state: success, fail, existing, updated - `exportDetails` shows a more detailed view of the export summary. This will include the `id` of the created record in the external system, and, if passed, the `externalId` that you send with each record. | | `error` | An object containing the error message | | `data_sizes` | The size of job files, in megabytes | | `resources_usage` | The amount of memory and CPU used. This can offer clues if your ETL script has memory leaks or inefficiencies | # Intermediary Formats Source: https://docs.hotglue.com/key-concepts/jobs/intermediary-formats hotglue intermediary formats explained Though most hotglue compatible taps write data following the [Singer spec](https://github.com/singer-io/getting-started/blob/master/docs/SPEC.md), storing and processing Singer data can be inefficient. To solve this, hotglue supports transforming your sync output into a more efficient storage format. Your [ETL](/transformation/overview) script processes the data from this format. hotglue supports four **Intermediary Formats**: | Format | Description | | - | - | | Singer | Does not transform synced Singer data. This can speed up your jobs by avoiding the intermediary transformation, but is much less storage efficient and is harder to work with in ETL | | CSV | Comma Separated Values. Larger file sizes than Parquet but offers more type flexibility | | Parquet | The Apache Parquet format. More storage efficient than CSV and offers strict type validation | | Parquet With Chunking | Writes Apache Parquet format in chunks, and compiles them together before ETL. | ## Debugging If you'd like to convert your singer data to these formats locally, read about [target-csv](/custom-connectors/target-csv) and [target-parquet](/custom-connectors/target-parquet). # Life Cycle Source: https://docs.hotglue.com/key-concepts/jobs/life-cycle hotglue job lifecycle explained hotglue job goes through several stages during the run. If you have a configured [webhooks](https://docs.hotglue.com/docs/jobs-webhooks) to receive job updates, you will receive a POST at each of these stages: | Lifecycle Step | Description | | - | - | | `JOB_CREATED` | The job has been created and queued to run. | | `DISCOVER_STARTED` | The job has begun fetching available tables and fields to sync. | | `DISCOVER_FAILED` | There was a fatal error fetching the available data. | | `SYNC_STARTED` | Data has begun to sync from the tap. | | `SYNC_FAILED` | There was a fatal error while syncing data from the tap. | | `SYNC_SUCCESS` | Data was successfully synced from the tap. | | `ETL_STARTED` | Transformation script will run on synced data. | | `ETL_FAILED` | There was a fatal error while the transformation script was running. | | `ETL_SUCCESS` | Transformation script completed successfully. | | `EXPORT_STARTED` | Export to the defined targets for the flow has begun. | | `EXPORT_FAILED` | There was a fatal error while exporting the data to one of the defined targets. | | `JOB_COMPLETED` | Job has completed successfully, and executor is shutting down. | # Scheduling Source: https://docs.hotglue.com/key-concepts/jobs/scheduling Learn to schedule jobs in hotglue # Job Scheduling hotglue runs data syncs using asynchronous jobs. To automate these jobs, you can configure a **sync schedule** in the UI so jobs run automatically without manual intervention. Scheduling is powered by **UNIX-style CRON expressions**, which determine when asynchronous jobs are triggered. CRON expressions can be configured directly through the UI. For example, the following expression would trigger every day at 12:00am UTC: ``` cron(0 0 * * *) ``` # How to configure the sync schedule ## Customizing schedules for Default tenant Sync schedules are configured from the Jobs section in the flow by selecting **Edit Schedule**. ![Edit Schedule Default](https://mintcdn.com/hotglue/Rs0SFILdHeRed2XO/images/Edit-Schedule-Default.png?fit=max\&auto=format\&n=Rs0SFILdHeRed2XO\&q=85\&s=a1a1e1916dff7bf996e11dcdfc8e752c) Then click the arrow to navigate to the **Select Schedule Type** page. ![Access Edit Schedule Default](https://mintcdn.com/hotglue/Rs0SFILdHeRed2XO/images/Access%20Edit%20Schedule%20Default%20\(2\).png?fit=max\&auto=format\&n=Rs0SFILdHeRed2XO\&q=85\&s=3a7e549ae234ac77290cc0b44a00b23e) From here, you can choose how often jobs should run and how the schedule is defined. hotglue supports three schedule types in the UI: **Fixed**, **Interval**, and **CRON**. ![Select Schedule Type Default](https://mintcdn.com/hotglue/Rs0SFILdHeRed2XO/images/Select%20Schedule%20Type%20Default%20\(3\).png?fit=max\&auto=format\&n=Rs0SFILdHeRed2XO\&q=85\&s=34ac708cee3f2e7281c99d44a84803c5) ***Fixed schedule*** A Fixed schedule triggers jobs at a specific time on a recurring basis. You can configure jobs to run hourly, daily, weekly, or monthly. For schedules that require a time, jobs will always run at the selected time. ![Fixed Schedule](https://mintcdn.com/hotglue/Rs0SFILdHeRed2XO/images/Fixed%20Schedule%20\(4\).png?fit=max\&auto=format\&n=Rs0SFILdHeRed2XO\&q=85\&s=dd2392c229c7fc3bc96725d8c8c32a9e) ***Interval schedule*** An Interval schedule triggers jobs after a defined amount of time has passed. Jobs can be set to run every specified number of minutes or hours. Each run is scheduled relative to the previous run. ![Interval Schedule](https://mintcdn.com/hotglue/Rs0SFILdHeRed2XO/images/Interval%20Schedule%20\(5\).png?fit=max\&auto=format\&n=Rs0SFILdHeRed2XO\&q=85\&s=ed5d83485765c87ad393bd2235bd7330) ***CRON expression*** A CRON expression schedule allows you to define a custom schedule using a UNIX-style CRON expression entered directly in the UI. This option is evaluated in UTC and is intended for advanced scheduling needs. ![CRON Expression](https://mintcdn.com/hotglue/Rs0SFILdHeRed2XO/images/CRON%20Expression%20\(6\).png?fit=max\&auto=format\&n=Rs0SFILdHeRed2XO\&q=85\&s=401cc30167c6deb9944a0e8d831a0d7e) ## Customizing schedules for tenants To configure a sync schedule for a specific tenant, first navigate to the desired tenant. ![Select Tenant View](https://mintcdn.com/hotglue/Rs0SFILdHeRed2XO/images/Select%20Tenant%20View.png?fit=max\&auto=format\&n=Rs0SFILdHeRed2XO\&q=85\&s=bab4af69e441f2cc90f28ce79b0e0097) From here, open the relevant flow and click **Edit Schedule** in the Jobs section. ![Edit Schedule for Tenant](https://mintcdn.com/hotglue/Rs0SFILdHeRed2XO/images/Edit%20Schedule%20for%20Tenant%20\(7\).png?fit=max\&auto=format\&n=Rs0SFILdHeRed2XO\&q=85\&s=d5b5b6bb207c9dabdbe2da240dca4ac6) Then click the arrow to navigate to the **Select Schedule Type** page and you can choose the desired **Schedule Type** for the tenant. # API To configure a sync schedule via the API, head to the [schedule endpoint docs](https://docs.hotglue.com/reference/jobs-schedule). ## Granular sync schedules [](https://docs.hotglue.com/docs/jobs-scheduling#granular-sync-schedules) You can use the API to configure any cron expression as a sync schedule. This is often helpful if you need jobs more frequent than hourly. You can use this to create a schedule for **default** tenant or any individual tenant. ## Schedule jitter Default schedules can include `schedule_jitter_minutes` to spread inherited tenant schedules across a random offset. Set an integer from `1` to `720`; use `null` to clear it. Jitter only applies when tenants inherit the **default** schedule. It does not change schedules created directly for individual tenants. ## Deleting or disabling schedules via API Use the [Delete jobs schedule](/api-reference/schedule-jobs/delete-jobs-schedule) endpoint to stop a sync schedule. Pass the optional `hard_delete` query parameter to control whether the schedule is removed or only disabled: | `hard_delete` | `default` tenant | Other tenants | | - | - | - | | `true` | Permanently deletes the schedule | Disables the schedule only (does not delete it) | | `false` or omitted | Disables the schedule | Disables the schedule | ## Ignoring default credentials [](https://docs.hotglue.com/docs/jobs-scheduling#ignoring-default-credentials) If you want to **avoid running scheduled jobs for your default credentials**, but are using your default sync schedule to cascade to new tenants, you can use the API to create a sync schedule for your **default** tenant and set `"state" = "disabled"` This will continue to apply your sync schedule to new tenants but will avoid running scheduled jobs with your default credentials. # Sync Jobs Source: https://docs.hotglue.com/key-concepts/jobs/sync-jobs What are sync jobs? # What is a sync job? hotglue uses sync jobs to move data between your product and the integrations your tenants link. hotglue is designed to sync data *incrementally*, meaning the first **sync job** pulls all historical data (from a specific *start date*), and subsequent sync jobs only pull the delta data (new or updated records). [https://www.loom.com/embed/beda3c54f5c34a8dbe0cfac05fec25e8?hide\_owner=true\&hide\_share=true\&hide\_title=true\&hideEmbedTopBar=true](https://www.loom.com/embed/beda3c54f5c34a8dbe0cfac05fec25e8?hide_owner=true\&hide_share=true\&hide_title=true\&hideEmbedTopBar=true) # Write Jobs Source: https://docs.hotglue.com/key-concepts/jobs/write-jobs How do write jobs work? ## What is a write job? A write job is a job where hotglue is writing data ***from*** your product ***to*** an integration. This is often referred to as **reverse ETL**. For example, if you wanted to write **Contacts** from your product to a tenant's Salesforce account, that would be an example of a write job in hotglue. ## How do you configure a flow to support write jobs? There are two types of flows that support write jobs: * v2 (bidirectional) * v1 (write) This option is presented when you first create a flow, as shown below: ![](https://mintcdn.com/hotglue/WfXuHr49lRpu5FgS/key-concepts/jobs/images/flow-types.png?fit=max\&auto=format\&n=WfXuHr49lRpu5FgS\&q=85\&s=74cee8d2969fd245df528c61e0ded3e9) We generally recommend using v2 flows whenever possible as they simplify the process of configuring bidirectional integrations (cases where you want to both read and write data to a connector). ## Trigger a write job via API In some cases you may want to pass the data you want to write via API instead of using a source. This is particularly useful if there is an action a tenant does in your product that should immediately send data to an integration. There are two ways to do this: ### Using the hotglue API source You can configure your flow to have the hotglue API as the source. This enables you to trigger a job using the `POST /jobs` endpoint with a `state` object containing the data you wish to write. This will queue a write job to asynchronously write the data. The request is slightly different depending on whether you're using a v2 flow or v1 write flow. ```bash v2 flow theme={null} curl --request POST \ --url https://api.hotglue.com/v2/{env_id}/{flow_id}/{tenant}/jobs \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "connector_id": "", "job_type": "write", "state": { "Contact": [ { "name": "Sam Altman", "email": "sam@openai.com", "type": "contact", "company_name": "OpenAI", "first_name": "Sam", "last_name": "Altman", "title": "CEO" } ] } }' ``` ```bash v1 write flow theme={null} curl --request POST \ --url https://api.hotglue.com/{env_id}/{flow_id}/{tenant}/jobs \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "state": { "Contact": [ { "name": "Sam Altman", "email": "sam@openai.com", "type": "contact", "company_name": "OpenAI", "first_name": "Sam", "last_name": "Altman", "title": "CEO" } ] }, "tap": "api" }' ``` ### Using the real-time write endpoint Alternatively, you can use the [real-time write endpoint](/api-reference/real-time/write), which sends the data synchronously. See demo below: [Real-time Write](https://www.loom.com/embed/7f13a823b68b4efcb1334e40c30df3b1?sid=e97e1d2f-b80a-4443-8b5c-a52d5d081f80) ```bash sample request theme={null} curl --request POST \ --url https://api.hotglue.com/{env_id}/{flow_id}/{tenant}/connectors/{connector_id}/{stream} \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{ "data": { "externalId": "222316", "firstname": "Tay", "lastname": "Kolma", "email": "tay.kolma@starwars.com" } }' ``` ## Viewing Write Job Results ### Record-by-record results in the dashboard After running a write job, you can view detailed results for each record in the hotglue dashboard. Navigate to your flow and select the specific job to see the **Export Details** page, which provides a comprehensive breakdown of your write operation: ![](https://mintcdn.com/hotglue/giDUIimQwa2r6Ye7/key-concepts/jobs/images/export-details.png?fit=max\&auto=format\&n=giDUIimQwa2r6Ye7\&q=85\&s=fd4ecba284d58456fab78701c2358459) * **Success Count**: Number of records successfully written to the integration * **Failed Count**: Number of records that failed to load For these records, the dashboard displays: * **External ID**: Your unique identifier for each record * **Error Message for failed records**: Detailed error information explaining why the record failed to load This allows you to quickly identify and troubleshoot issues with specific records, such as validation errors, invalid data, or rate limiting issues from the target system. ## Features hotglue has several out of the box features that make working with writes significantly easier. Read more about them below. ### External Id When writing data to a connector there are many cases where you may want to later *update* that same record again. A handful of systems (such as Salesforce and NetSuite) natively support the concept of an **external id** – this essentially allows you to use your own ID to reference an object rather than having to store the internal id of that system. hotglue supports external id upserts natively in our [target-hotglue-sdk](https://gitlab.com/hotglue/target-hotglue-sdk) – this means that even systems that **do not** natively support external ids can support external ids via hotglue. Check out the demo below with HubSpot: [Upserts with External Id](https://www.loom.com/embed/1406a17c98e04ae993d2b48a0a86646b?sid=ff947bd9-c0d5-42c8-9a58-b4fb03902d58) The other advantage of using an **external id** is that it makes it easy to parse the result of a write job, as the external id is returned back to you. See the sample below where we are writing `contacts` to the HubSpot connector: ```json input theme={null} { "data": { "externalId": "222316", "firstname": "Tay", "lastname": "Kolma", "email": "tay.kolma@starwars.com" } } ``` ```json result theme={null} { "jobId": "83r3Vh", "taskId": "d27046ba-50d8-46b5-8290-ffc6b2efcb77", "state": { "bookmarks": { "contacts": [ { "hash": "a7c3c19f2bae3dcbe627b89a5bcd1d6453ab73a95369fe79726544169c25a075", "success": true, "id": "289784955095", "externalId": "222316" } ] }, "summary": { "contacts": { "success": 1, "fail": 0, "existing": 0, "updated": 0 } } } } ``` ### Saving Record IDs in Snapshots For write jobs, hotglue can automatically save the mapping between your external IDs and the remote system's IDs in [snapshots](/transformation/snapshots). This is particularly useful for maintaining a persistent record of which records have been written and their corresponding IDs in the target system. To enable this feature, simply toggle on **"Save records IDs in snapshots folder"** in your job settings. When enabled, hotglue will automatically create snapshot files containing: ![](https://mintcdn.com/hotglue/giDUIimQwa2r6Ye7/key-concepts/jobs/images/Records_ID_setup.png?fit=max\&auto=format\&n=giDUIimQwa2r6Ye7\&q=85\&s=342883d0d66459968c7146d6e2612fe9) * **InputId**: Your external ID or unique identifier * **RemoteId**: The ID assigned by the target integration (e.g., Salesforce record ID, HubSpot contact ID) * **CustomData**: JSON metadata per record (from the target, and from fields you choose in the ETL export) From transformation scripts, use gluestick `target_state_fields` and `target_state_include_hash` on `to_singer` or `to_export` to persist ETL column values and the target record hash in `CustomData`. See [Target state metadata](/transformation/gluestick/export#target-state-metadata). These snapshot files are accessible from the **Snapshots Manager** tab in your tenant page. ![](https://mintcdn.com/hotglue/giDUIimQwa2r6Ye7/key-concepts/jobs/images/Snapshot_Manager.png?fit=max\&auto=format\&n=giDUIimQwa2r6Ye7\&q=85\&s=7d0c73e8d75c7152696d0ab62b277b8f) This is an example of snapshot created by Hotglue ![](https://mintcdn.com/hotglue/giDUIimQwa2r6Ye7/key-concepts/jobs/images/Snapshot_example.png?fit=max\&auto=format\&n=giDUIimQwa2r6Ye7\&q=85\&s=81bbdf04ba38668141e2eebc1b809ceb) Learn more about snapshots and how to use them programmatically in transformation scripts in the [Snapshots documentation](/transformation/snapshots). # Tenants Source: https://docs.hotglue.com/key-concepts/tenants What are tenants? ## What is a tenant? A **tenant** is one of your customers who has connected at least one integration via hotglue. ## What is an active tenant? An **active tenant** is any tenant that has run at least one sync job within the last 30 days. Billing is calculated based on the number of active tenants. Learn more about tenants and how they are used in the walkthrough below: [https://www.loom.com/embed/5b7713c84a2b42eb9c35287fe52c5160?hide\_owner=true\&hide\_share=true\&hide\_title=true\&hideEmbedTopBar=true](https://www.loom.com/embed/5b7713c84a2b42eb9c35287fe52c5160?hide_owner=true\&hide_share=true\&hide_title=true\&hideEmbedTopBar=true) ## What is a subtenant? **Subtenants** are used when a single tenant needs multiple distinct connections with the same connector. [Learn more about subtenants](/key-concepts/tenants/subtenants). ## Creating and deleting tenants Tenants are automatically created when you link a connection with a new `tenant_id`. This can be done via magic links, the widget, or via the API. You can also clone or delete tenants via your dashboard or API: ### Clone tenants to another environment Cloning may be useful if you are migrating to a fresh environment, or if you want to test some changes in a QA environment on a real tenant. Before cloning, you must first ensure that the corresponding flows and sources/connectors have already been cloned to those environments. Once that's done: 1. Navigate to the **Tenants** tab in hotglue 2. Click on the name of the tenant that you want to clone. 3. Click `Clone Tenant` from the tenant management drawer. 4. Select the environment to clone your tenant into. Cloning your tenant will copy over the `linkedSources`, `linkedTargets`, and `linkedConnectors` to your new environment. That includes any forks that you have set on ETLs and field maps, alongside the incremental state. Cloned tenants will not automatically transfer snapshots, schedules, triggers, or job history. ### Delete tenants In some cases, you may want to completely delete a tenant and its data from hotglue. You can do this [programmatically via the API](/api-reference/manage-tenants/delete-a-tenant), or from your hotglue dashboard: To delete a tenant: 1. Navigate to the **Tenants** tab in hotglue 2. Click on the name of the tenant that you want to delete. 3. Click `Delete Tenant` from the tenant management drawer. Tenant deletions are "hard" deletions, meaning that any sensitive data--including configs, snapshots, and job cache data--are cleared without a retention period. If you want to keep a tenant's data but stop its jobs, you can just disable the tenant's job schedules directly. # The Default Tenant Source: https://docs.hotglue.com/key-concepts/tenants/default-tenant What is the default tenant? ## What is the default tenant? The **default tenant** is the administrative tenant used by *you*, the user. Hotglue refers to the administrative tenant as **default** because: * In a **Read Flow**, your tenants will default to using the **default tenant's** [linked target](/key-concepts/connectors/v1-targets/overview) * In a **Write Flow**, your tenants will default to using the **default tenant's** [linked source](\(/key-concepts/connectors/v1-sources/overview\)) * In a **V2 Bidirectional Flow**, your tenants will default to using the **default tenant's** linked source and/or target. ## Support sources, targets and connectors Before your tenants can link a connector with their own credentials, you must link that connector within that flow using the **default tenant**. Linking with the **default tenant** creates a [supported source](/key-concepts/connectors/v1-sources/overview#what-is-a-supported-source) for that flow. Similarly when you link V1 Targets and V2 Connectors with your **default tenant**, you create [supported targets](/key-concepts/connectors/v1-targets/overview#what-is-a-supported-target) and [supported connectors](/key-concepts/connectors/connectors#what-is-a-supported-connector) respectively. ## Billing The **default tenant** is not counted in your billed active tenant count. # Tenant Metadata Source: https://docs.hotglue.com/key-concepts/tenants/metadata Map tenant IDs to names, plans, and other identifiers using metadata Tenant metadata is a tool to associate the tenant IDs of your customers with meaningful user data, such as external IDs, licenses, or plain-text names. This is useful if you use UUIDs or other non-readable strings as tenant IDs. With metadata, you can associate an unreadable tenant ID `b3ce717c-9ee3-4c80-a3d1-de42f3563496` with the company name `Apple, Inc` and Stripe Customer ID `cus_P5iEJpWPKP3xXI`. ![](https://files.readme.io/18fa25e-58ba762-hotglue-metadata-management_1-min.png) Tenant metadata is always accessible via: 1. API 2. [Job Lifecycle webhooks](/environment-settings/webhooks) 3. Tenant configs, for use in your ETL scripts 4. The admin panel **Tenant** dashboard You can also add metadata to tenants via [the widget](#using-the-widget), [API](#using-the-api) or your [hotglue admin panel](#using-the-admin-panel). # How to add tenant metadata There is no central "custom field" list in hotglue. Metadata is added per-tenant, and types are not enforced. That means that you can add any metadata field to any tenant without validation ## Using the widget Metadata can be added using the built-in `tenantMetadata` option in the widget. When any widget function is called with a `tenantMetadata` option object, the tenant ID will be associated with your chosen metadata. This is supported in the Javascript widget (`hotglue.com/widgetv2.js`) or in React versions ≥ 1.4.9. For example, you can add tenant metadata using the javascript `HotGlue.link` function as below: ``` HotGlue.link(tenant, flow, connector, false, { tenantMetadata: { "Name": "OpenAI", "Email": "sama@openai.com" "Stripe ID": "cus_P5iEJpKWPP3xXl" } } ) ``` > 🚧 Note: tenantMetadata overwrites existing metadata fields > > When you pass tenantMetadata to the widget, hotglue overwrites your metadata object with whatever is passed to the widget. If you do not pass all metadata values to the widget, this becomes a destructive action. ## Using the API Metadata can be added with a **PUT** to the `/metadata` endpoint. Learn more about tenant metadata APIs [here](/api-reference/manage-tenants/set-tenant-metadata). ## Using the admin panel Metadata can be added directly from the hotglue admin panel. To add metadata: 1. Navigate to the tenant management dashboard 2. Click on any tenant (not the 👁 icon) to bring up the tenant management panel 3. Navigate to the Metadata tab 4. Type in a field name, type, and value 5. Click `+` to add your new metadata field ![](https://files.readme.io/58ba762-hotglue-metadata-management.png) You can then configure which metadata is shown by clicking Edit Columns in your Tenant list, or edit metadata by clicking the pencil icon next to a field in your tenant management panel. # Differences between tenant metadata vs. tenant config Tenant metadata is stored in the tenant config. That means that you can technically utilize metadata in any way that you use the tenant config--for example, as flags in ETL scripts. Inside the tenant config, metadata is structured like below: ```json tenant-config.json theme={null} { "hotglue_metadata": { "metadata": { "Company": "Apple, Inc.", "External Id": "appleinc", "Website": "apple.com", "Contact Email": "tim@apple.com", "Churn Risk?": false, "Stripe Plan": "enterprise", "Stripe ID": "cus_P5iEJpWPKP3xXl" } }, // other tenant config objects go here } ``` The primary difference is that metadata is exposed in more places (webhooks, admin panel) and it cannot be nested. This makes it an excellent candidate for simple user information like plans and company names, but a poor candidate for nested configuration objects. | Properties | Tenant Config | Tenant Metadata | | :- | :- | :- | | Supports nested objects | ✅ | ❌ | | Can be managed via the admin panel or API | ✅ | ✅ | | Can be managed via widget embed code | ❌ | ✅ | | Sent in job lifecycle webhooks | ❌ | ✅ | # Subtenants Source: https://docs.hotglue.com/key-concepts/tenants/subtenants **Subtenants** are used when a single tenant needs to link multiple instances of **the same connector**, in the same flow. This might happen when you have: * A Shopify connection with multiple stores * A Quickbooks Online connection with multiple Quickbooks companies > [!TIP] > > **For connections across different connectors and/or flows, subtenants are not necessary.** > If your customers are only linking a specific Salesforce organization or a single Netsuite account, you can stick to regular tenants. # Quick Setup 1. Navigate to Settings > Widget 2. Toggle on **Enable subtenant functionality** Once enabled, tenants with a `_` delimeter will be recognized as a subtenant. You can then create subtenants using either: * **API**: Use the reserved naming convention `{ROOT TENANT}_{SUB TENANT ID}`. * **Widget**: Use the dropdown subtenant manager in the quick actions tab. ## How subtenants work Subtenants follow a specific naming pattern: `{ROOT_TENANT}_{SUBTENANT_ID}`. For example, `acme_2` represents a subtenant where: * `acme` is the root tenant * `2` is the subtenant identifier This naming convention helps maintain the relationship while allowing individual management across APIs, CLI, and the admin panel. ## Benefits of using subtenants Using subtenants instead of separate tenants offers three key advantages: * **Billing**: Subtenants are billed as a single tenant, based on the `root_tenant_id`. * **Shared links**: The same root tenant ID + JWT token can manage all of its subtenants. You can also fetch the root tenant's connection (`linkedSource`/`linkedConnector`) to retrieve all associated subtenants. * **ETL functions**: Parents and subtenants have privileged access to each others' snapshot data in ETL scripts. # Debugging a script Source: https://docs.hotglue.com/transformation/debugging-a-script This guide teaches you how to debug a python transformation script ## Before you start This guide assumes you have already launched a JupyterLab workspace, as described in the [Transformations Overview](/transformation/python-scripts#start-the-jupyterlab-workspace). ## Access prior job logs and data If you're debugging a job failure, you can learn more about the cause of failure by reading the logs. To start, navigate to the job that failed (this could be under a specific tenant): ![](https://files.readme.io/b559e1d-0c837cf-Screen_Shot_2022-12-27_at_3.02.05_PM-min.png) Click on the download icon next to the job. A zip file will be generated containing the raw data that was was generated during that job. The directory structure is exactly the same as described on [the transformation script docs](https://docs.hotglue.com/docs/writing-a-basic-script#standard-directories). By clicking the job name, you can access the logs and understand any errors that may have occurred: ![Job logs + the "down" arrow to view more recent logs](https://files.readme.io/bd0d376-505b035-Screen_Shot_2022-12-27_at_3.04.13_PM-min.png) Job logs + the 'down' arrow to view more recent logs > [!TIP] > > ### **Find errors quickly** > > To speed up debugging, click the down arrow to quickly scan to the most recent logs. ## Clone a job While in a JupyterLab workspace, you can **clone** the data from a prior job. This is especially useful if you're debugging a specific job that failed, or you need some testing data to develop a script. Inside of Jupyter, select the hotglue tab and press clone job. ![3068](https://files.readme.io/9700d02-Screen_Shot_2021-12-15_at_4.02.21_PM.png "Screen Shot 2021-12-15 at 4.02.21 PM.png") Select clone job Jupyter will present you with a list of the most recent jobs. Press select on the one you would like to clone. ![3068](https://files.readme.io/1360e6c-Screen_Shot_2021-12-15_at_4.03.55_PM.png "Screen Shot 2021-12-15 at 4.03.55 PM.png") Choose which job to clone Once the data is cloned, you'll see a success message as below, and the data will be populated in the `sync-output` folder. ![3068](https://files.readme.io/9e6f6b1-Screen_Shot_2021-12-15_at_4.04.34_PM.png) Job clone success You can preview the data that was cloned in JupyterLab by opening the `sync-output` folder. As you can see, my `subscribe_list` data was cloned: ![3068](https://files.readme.io/3a4d04c-Screen_Shot_2021-12-15_at_4.04.57_PM.png "Screen Shot 2021-12-15 at 4.04.57 PM.png") Preview cloned data ## Test the script Now that your data is cloned, you can run your transform script normally and it should pick up the data automatically. ![3068](https://files.readme.io/4bc1a19-Screen_Shot_2021-12-15_at_4.08.39_PM.png "Screen Shot 2021-12-15 at 4.08.39 PM.png") Run entire transformation script If your script fails, you will see the error in the notebook (`etl.ipynb`). From there, you can change your script and run against the data again. When your script works correctly, you should see the output files in the `etl-output` folder: ![3068](https://files.readme.io/c18460c-Screen_Shot_2021-12-15_at_4.09.20_PM.png "Screen Shot 2021-12-15 at 4.09.20 PM.png") Transformation script output That's all there is to testing your script in hotglue! # getCatalogSchema Source: https://docs.hotglue.com/transformation/gluestick-ts/getCatalogSchema ## getCatalogSchema A function for retrieving and processing schema information from a Singer catalog for a specific stream. This function extracts the schema definition and ensures proper formatting for array types. ### Basic Usage ```typescript theme={null} import * as gs from '@hotglue/gluestick-ts'; const schema = gs.getCatalogSchema("users"); console.log(schema.properties); ``` ### Key Methods *** ## getCatalogSchema(stream: string): SingerHeaderMap Retrieves the schema definition for a specific stream from the Singer catalog and processes it for proper formatting. ### Usage ```typescript theme={null} // Get schema for a specific stream const userSchema = gs.getCatalogSchema("users"); // Use schema with export functions gs.toExport(df, "users", "./output", { exportFormat: 'singer', schema: userSchema }); ``` ### Parameters * `stream` (string): Name of the stream to get schema for (can be stream name or tap\_stream\_id) ### Returns * `SingerHeaderMap`: Processed schema object with proper type definitions and array handling ### Schema Structure The returned schema object has the following structure: ```typescript theme={null} { type: ["object", "null"], properties: { // Stream properties with their types and definitions } } ``` ### Error Handling The function throws errors in the following cases: * **No catalog found**: When the catalog file cannot be read or doesn't exist * **Stream not found**: When the specified stream doesn't exist in the catalog ```typescript theme={null} try { const schema = gs.getCatalogSchema("nonexistent_stream"); } catch (error) { console.error(error.message); // "No schema found in catalog for stream nonexistent_stream" } ``` ## Common Patterns ### Get Schema for Multiple Streams ```typescript theme={null} import * as gs from '@hotglue/gluestick-ts'; const reader = new gs.Reader(); const availableStreams = reader.keys(); const schemas = {}; for (const stream of availableStreams) { try { schemas[stream] = gs.getCatalogSchema(stream); } catch (error) { console.warn(`No schema found for ${stream}:`, error.message); } } ``` ### Notes * Requires a valid Singer catalog file in the project directory * The function accesses the catalog through the Reader class's private `readCatalog` method * Array types are automatically normalized to include `items` properties * The returned schema is compatible with Singer export formats * Schema properties are preserved as-is from the original catalog # Introduction to Gluestick TS Source: https://docs.hotglue.com/transformation/gluestick-ts/overview A Typescript library for efficient ETL processes, optimized for hotglue Gluestick is an open source ETL toolkit developed and maintained by hotglue. It is optimized for usage in hotglue pre-processing scripts and built on top of the [Polars library](https://pola-rs.github.io/nodejs-polars/) The code is available on GitHub and is free to use under the MIT license. > [card] [GitHub Repository](https://github.com/hotgluexyz/gluestick-ts) > > Access the complete source code, contribute, or report issues through our GitHub repository. Star us to show support! ## Getting started with gluestick ```bash theme={null} # Install from NPM npm install @hotglue/gluestick-ts # Import utilities import * as gs from '@hotglue/gluestick-ts'; ``` You can find example JS and TS transformation scripts [here](https://github.com/hotgluexyz/etl-scripts-ts). ## Key Features * Robust ETL utilities for data processing * Singer protocol integration * Advanced JSON and object handling * Production-ready error handling ## Core Functions > [card] [Reader](/transformation/gluestick-ts/reader) > > Class for reading sync-output data. Provides methods to list and read input streams. > [card] [toExport](/transformation/gluestick-ts/toExport) > > Class for writing etl-output data in desired format (Parquet, CSV, etc) # Data Reading Functions Source: https://docs.hotglue.com/transformation/gluestick-ts/reader ## Reader A class for reading ETL files from the sync-output directory. This is the recommended way to read ETL files as it provides consistent error handling and metadata access. ### Basic Usage ```typescript theme={null} import * as gs from '@hotglue/gluestick-ts'; const reader = new gs.Reader(); ``` ### Key Methods *** ## get(stream: string, options): DataFrame Read a specific stream as a [Polars](https://pola-rs.github.io/nodejs-polars/) DataFrame ### Usage ```typescript theme={null} // Basic reading const df = reader.get("users"); // Type the dataframe according to the catalog const df = reader.get("users", { catalogTypes: true }); ``` ### Parameters * `stream` (str): Name of stream to read * `options` (obj) * `catalogTypes`: (boolean) - Use catalog for automatic type inference * Other options will be passed through to Polars when reading. See [ReadCSV](https://pola-rs.github.io/nodejs-polars/interfaces/ReadCsvOptions.html) and [ReadParquet](https://pola-rs.github.io/nodejs-polars/interfaces/ReadParquetOptions.html) options for more information *** ## getPk(stream: string): string\[] Gets primary key(s) for a stream from catalog ### Usage ```typescript theme={null} const primaryKeys = reader.getPk('users'); console.log(primaryKeys) // ["user_id", "region_id"] ``` ### Parameters * `stream` (string): Name of stream to get primary keys for ### Returns * `string[]`: Array of primary key column names *** ## keys(): string\[] Gets all available stream names from the input files. ### Usage ```typescript theme={null} const availableStreams = reader.keys(); console.log(availableStreams); // ["users", "orders", "products"] ``` ### Returns * `string[]`: Array of all available stream names ## Common Patterns ### Iterating through multiple streams ```typescript etl.ts theme={null} import * as gs from '@hotglue/gluestick-ts'; // iterate through each stream in the input directory const input = new gs.Reader(); const availableStreams = input.keys(); for (const key of availableStreams) { const inputDf = input.get(key, { catalogTypes: true }); } ``` # Snapshotting functions Source: https://docs.hotglue.com/transformation/gluestick-ts/snapshots ## `readSnapshots` Function This function reads snapshot data from either Parquet or CSV files for a specified stream. **Parameters**: * `stream` (string): The name of the stream to read snapshots for. * `snapshotDir` (string): The directory containing the snapshot files. * `options` (object): Optional. CSV read options. **Returns**: * A `Polars.DataFrame` containing the snapshot data, or `null` if no snapshot exists. **Example Usage**: ```typescript theme={null} const snapshot = readSnapshots('users', '/path/to/snapshot/dir'); if (snapshot) { console.log('Snapshot loaded:', snapshot); } else { console.log('No snapshot available.'); } ``` ## `snapshotRecords` Function This function creates or updates snapshot records for a data stream with options for deduplication, type coercion, and more. **Parameters**: * `streamData` (Polars.DataFrame or null): The data to snapshot. * `stream` (string): The name of the stream. * `snapshotDir` (string): The directory to store snapshot files. * `pk` (string): Primary key for deduplication. Defaults to "id". * `justNew` (boolean): Whether to return only new data instead of the full snapshot. * `useCsv` (boolean): Whether to write snapshots as CSV instead of Parquet. * `coerceTypes` (boolean): If true, types are coerced to match `streamData` dtypes. * `localizeDatetimeTypes` (boolean): If true, converts datetime columns to UTC. * `overwrite` (boolean): If true, overwrites the snapshot entirely instead of merging. * `options` (object): Additional options for CSV reading. **Returns**: * The updated `Polars.DataFrame` of the snapshot, merged according to the primary key specified. **Example Usage**: ```typescript theme={null} const df = new Polars.DataFrame({ columns: ['user_id', 'name'] }); const dfWithSnapshottedData = snapshotRecords(df, 'users', '/path/to/snapshot/dir'); console.log('Updated Snapshot:', dfWithSnapshottedData); ``` # toExport Source: https://docs.hotglue.com/transformation/gluestick-ts/toExport ## toExport A function for exporting Polars DataFrames to various file formats with configurable options. This is the recommended way to export ETL data as it provides consistent formatting and multiple export format support. ### Basic Usage ```typescript theme={null} import * as gs from '@hotglue/gluestick-ts'; const df = pl.DataFrame({...}); gs.toExport(df, "users", "./etl-output"); ``` ### Key Methods *** ## toExport(data, name, outputDir, options) Exports a Polars DataFrame to the specified output directory in the chosen format. ### Usage ```typescript theme={null} // Basic singer export gs.toExport(df, "users", "./etl-output"); // Export with custom options gs.toExport(df, "users", "./etl-output", { exportFormat: 'parquet', keys: ['user_id'], outputFilePrefix: 'processed_' }); ``` ### Parameters * `data` (pl.DataFrame): Polars DataFrame to export * `name` (string): Name for the output file * `outputDir` (string): Directory path for output files * `options` (ExportOptions): Optional configuration object *** ## ExportOptions Interface Configuration options for the export function. ### Properties * `keys?` (string\[]): Primary keys for the dataset (used in singer format) * `exportFormat?` ('csv' | 'json' | 'jsonl' | 'parquet' | 'singer'): Output format (defaults to 'singer' or DEFAULT\_EXPORT\_FORMAT env var) * `outputFilePrefix?` (string): Prefix to add to output filenames * `stringifyObjects?` (boolean): Whether to stringify object values * `reservedVariables?` (`Record`): Custom variables for prefix formatting * `allowObjects?` (boolean): Whether to allow object values in singer format (defaults to true) * `schema?` (SingerHeaderMap): Singer schema definition ## Common Patterns ### Iterating through multiple streams and exporting ```typescript theme={null} import * as gs from '@hotglue/gluestick-ts'; // iterate through each stream in the input directory const input = new gs.Reader(); const availableStreams = input.keys(); for (const key of availableStreams) { const inputDf = input.get(key, { catalogTypes: true }); // Export the transformed data gs.toExport(inputDf, key, "./etl-output"); } ``` # Data Transformation Functions Source: https://docs.hotglue.com/transformation/gluestick/data-transformation Functions for cleaning, mapping, and transforming data in pandas DataFrames ## clean\_convert Recursively cleans None values from lists and dictionaries, handling nested structures and converting datetime objects to ISO format. ### Installation ```python theme={null} from gluestick.etl_utils import clean_convert ``` ### Basic Usage ```python theme={null} # Clean dictionary cleaned_dict = clean_convert({ 'name': 'John', 'age': None, 'scores': [10, None, 20] }) # Clean nested structures cleaned_nested = clean_convert({ 'user': { 'name': 'John', 'details': [ {'score': 10}, {'score': None} ] } }) ``` ### Parameters * `input` (dict, list): Input data structure to clean * Handles: * Dictionaries * Lists * Datetime objects * Scalar values ### Returns Cleaned data structure with None values removed *** ## map\_fields Maps row values according to a specified mapping dictionary, supporting nested structures and arrays. ### Usage ```python theme={null} from gluestick.etl_utils import map_fields # Basic field mapping mapping = { 'user_name': 'name', 'user_age': 'age' } result = map_fields(row, mapping) # Nested mapping mapping = { 'user': { 'fullName': 'name', 'age': 'age' }, 'scores': ['test_scores'] } result = map_fields(row, mapping) ``` ### Parameters * `row` (dict): Source data row * `mapping` (dict): Mapping configuration * Keys: Target field names * Values: Source field names or nested mappings ### Returns Dictionary with mapped values *** ## rename Renames DataFrame columns using JSON format with support for type conversion. ### Usage ```python theme={null} from gluestick.pandas_utils import rename # Basic column renaming new_df = rename(df, { 'old_name': 'new_name', 'previous': 'current' }) # Select specific columns new_df = rename(df, ['col1', 'col2', 'col3']) ``` ### Parameters * `df` (pd.DataFrame): Input DataFrame * `target_columns` (dict, list): * dict: Mapping of old to new column names * list: Columns to select ### Returns DataFrame with renamed columns ### Notes * Supports both renaming and column selection * Preserves data types * Returns original DataFrame if no mapping provided * Only renames existing columns *** ## localize\_datetime Converts DataFrame datetime columns to UTC timezone, handling both naive and timezone-aware timestamps. ### Usage ```python theme={null} from gluestick.etl_utils import localize_datetime # Localize single column df['timestamp'] = localize_datetime(df, 'timestamp') # Process multiple columns for col in ['created_at', 'updated_at']: df[col] = localize_datetime(df, col) ``` ### Parameters * `df` (pd.DataFrame): Input DataFrame * `column_name` (str): Name of datetime column to localize ### Returns Series with localized datetime values *** ## deep\_convert\_datetimes Recursively transforms all datetime objects to ISO format strings within nested data structures. ### Usage ```python theme={null} from gluestick.singer import deep_convert_datetimes # Convert nested structure converted = deep_convert_datetimes({ 'created': datetime.now(), 'items': [ {'date': datetime.now()}, {'date': datetime.now()} ] }) # Convert list of records converted_list = deep_convert_datetimes([ {'timestamp': datetime.now()}, {'timestamp': datetime.now()} ]) ``` ### Parameters * `value` (any): Input value or data structure * Handles dictionaries, lists, datetime objects * Processes nested structures recursively ### Returns Data structure with datetime objects converted to ISO format strings ### Notes * Uses "%Y-%m-%dT%H:%M:%S.%fZ" format * Handles both datetime and date objects * Preserves original data structure * Safe for non-datetime values ## exception **Recommended**: Standardized error handling and logging for ETL pipelines. ### Usage ```python theme={null} from gluestick.etl_utils import exception try: # Your ETL code here process_data() except ValueError as e: exception(e, ROOT_DIR, "Error processing data") # With additional context try: transform_data() except Exception as e: exception( e, ROOT_DIR, f"Failed processing stream {stream_name}" ) ``` ### Parameters * `exception` (Exception): Caught exception * `root_dir` (str): Directory for error log * `error_message` (str): Additional context message ### Notes * Creates consistent error format * Logs errors to 'errors.txt' * Preserves original exception details * Adds contextual information *** ## Common Patterns ### Processing DateTime Data ```python theme={null} import gluestick as gs from datetime import datetime def process_timestamps(df): # Localize timezone columns datetime_cols = ['created_at', 'updated_at'] for col in datetime_cols: df[col] = gs.localize_datetime(df, col) # Process nested data with timestamps df['metadata'] = df['metadata'].apply(gs.deep_convert_datetimes) return df # Clean and map data with timestamps def transform_data(input_data): # First clean None values and convert dates cleaned = gs.clean_convert(input_data) # Define mapping with timestamp fields mapping = { 'user': { 'created': 'created_at', 'modified': 'updated_at' } } # Map and process fields return gs.map_fields(cleaned, mapping) ``` # Data Export & Error Handling Source: https://docs.hotglue.com/transformation/gluestick/export Functions for exporting data to various formats and handling errors in ETL pipelines ## to\_export **Recommended**: Universal export function supporting multiple output formats with schema validation and customization options. ### Installation ```python theme={null} import gluestick as gs ``` ### Basic Usage ```python theme={null} # Basic export to default format (Singer) gs.to_export(df, "users", OUTPUT_DIR, keys=['id']) # Export to specific format gs.to_export( df, "users", OUTPUT_DIR, export_format="parquet", stringify_objects=True ) ``` ### Parameters * `data` (pd.DataFrame): DataFrame to export * `name` (str): Output file name/stream name * `output_dir` (str): Directory for output files * `keys` (list): Primary key fields * `unified_model` (pydantic.BaseModel): Pydantic model for schema validation * `export_format` (str): Output format ('singer', 'parquet', 'json', 'jsonl', 'csv') * `output_file_prefix` (str): Optional prefix for output files * `schema` (dict): Custom schema for Singer format * `stringify_objects` (bool): Convert complex objects to strings for Parquet * `target_state_fields` (list | str): Column names from export records to persist in target state `customData` (Singer export only) * `target_state_include_hash` (bool): Persist the target SDK record hash in target state `customData` (Singer export only) ### Returns None (writes files to specified directory) ### Notes * Uses environment variables for format defaults * Supports prefix override per stream * Handles complex data types appropriately per format * Validates against Pydantic models when provided *** ## to\_singer **Recommended**: Specialized function for exporting data to Singer format with comprehensive type handling. ### Usage ```python theme={null} import gluestick as gs # Basic Singer export gs.to_singer(df, "users", OUTPUT_DIR, keys=['id']) # With schema validation gs.to_singer( df, "users", OUTPUT_DIR, keys=['id'], allow_objects=True, schema=custom_schema ) # Persist ETL fields in target state customData gs.to_singer( df, "contacts", OUTPUT_DIR, keys=["externalId"], target_state_fields=["email", "status"], target_state_include_hash=True, ) ``` ### Parameters * `df` (pd.DataFrame): DataFrame to export * `stream` (str): Singer stream name * `output_dir` (str): Output directory * `keys` (list): Primary key fields * `filename` (str): Output filename (default: 'data.singer') * `allow_objects` (bool): Enable complex object handling * `schema` (dict): Custom schema definition * `unified_model` (pydantic.BaseModel): Pydantic model for validation * `target_state_fields` (list | str): Column names from export records to persist in target state `customData` * `target_state_include_hash` (bool): Persist the target SDK record hash in `customData` ### Notes * Handles datetime conversions automatically * Supports catalog-based schemas * Validates data against provided schemas * Creates Singer-compliant output files *** ## Target state metadata Pass `target_state_fields` and/or `target_state_include_hash` when you want hotglue to store extra per-record data on the target state after a write job. The same options work on `to_singer` and `to_export` when `export_format` is `singer`. * `target_state_fields`: columns to persist in target state `customData`. Field names in `target_state_fields` refer to columns on records as your ETL sends them to the target. A single string is treated as one field. * `target_state_include_hash`: persist the target SDK record hash in target state `customData`. When you set these options, Gluestick adds an `x-hotglue` block on the stream SCHEMA message in `data.singer`. The target SDK reads that configuration and copies the requested values into each record's `customData` in the target state output (merged with any `customData` the target already emits). That `customData` is also stored in the tenant snapshots folder when [**Save records IDs in snapshots**](/key-concepts/jobs/write-jobs#saving-record-ids-in-snapshots) is enabled on the flow. The usual reason to set this on export is so a **later transformation run** can read what was stored on the last write job. Typical uses include comparing the saved `hash` (`target_state_include_hash`) to detect unchanged records, reusing values you pushed previously, or joining snapshot fields to incoming sync data on `externalId` before the next export. **Example:** load the write snapshot and merge `CustomData` fields that match your `target_state_fields`, plus `hash` when you enabled `target_state_include_hash`: ```python theme={null} import json import os import gluestick as gs import pandas as pd snapshot_df = gs.read_snapshots(f"contacts_{os.environ['FLOW']}", f"{ROOT_DIR}/snapshots") if snapshot_df is not None and not snapshot_df.empty: rows = snapshot_df.dropna(subset=["CustomData"]) meta = pd.DataFrame( rows["CustomData"].map(json.loads).tolist(), index=rows["InputId"], ) df = df.merge(meta[["status", "hash"]], left_on="externalId", right_index=True, how="left") ``` *** ## Common Patterns ### Handling Complex Exports ```python theme={null} import gluestick as gs # Multiple format export def multi_format_export(df, name): for format in ['singer', 'parquet', 'json']: try: gs.to_export( df, name, OUTPUT_DIR, export_format=format ) except Exception as e: gs.exception( e, ROOT_DIR, f"Failed {format} export for {name}" ) ``` # JSON & Object Handling Source: https://docs.hotglue.com/transformation/gluestick/json Functions for processing and transforming JSON and object data in pandas DataFrames ## explode\_json\_to\_cols Converts JSON array columns into separate columns, with one column per array value. ### Usage ```python theme={null} from gluestick.pandas_utils import explode_json_to_cols # Basic column explosion df = explode_json_to_cols(df, 'array_column') # With options df = explode_json_to_cols( df, 'array_column', drop=True, inplace=False ) ``` ### Parameters * `df` (pd.DataFrame): Input DataFrame * `column_name` (str): Column containing JSON arrays * `drop` (bool): Whether to drop original column * `inplace` (bool): Modify DataFrame in place * `parser` (function): Custom parsing function (optional) ### Returns DataFrame with array values expanded into separate columns *** ## explode\_json\_to\_rows Takes a column containing an array of objects and expands it into multiple rows, creating columns for each object property. ### Usage ```python theme={null} from gluestick.pandas_utils import explode_json_to_rows # Basic explosion df = explode_json_to_rows(df, 'array_column') # With nesting control df = explode_json_to_rows( df, 'array_column', drop=True, max_level=2 ) ``` ### Parameters * `df` (pd.DataFrame): Input DataFrame * `column_name` (str): Column containing JSON arrays * `drop` (bool): Whether to drop original column * `max_level` (int): Maximum nesting level for flattening * `parser` (function): Custom parsing function (optional) ### Returns DataFrame with array objects expanded into separate rows *** ## json\_tuple\_to\_cols Convert JSON tuple columns into separate columns based on key-value pairs. Useful for transforming nested JSON data into a flattened DataFrame structure. ### Installation ```python theme={null} from gluestick.pandas_utils import json_tuple_to_cols ``` ### Basic Usage ```python theme={null} # Basic conversion with default settings df = json_tuple_to_cols(df, 'json_column') # Custom key-value mapping config = { 'cols': {'key_prop': 'CategoryName', 'value_prop': 'CategoryValue'}, 'look_up': {'key_prop': 'name', 'value_prop': 'value'} } df = json_tuple_to_cols(df, 'json_column', col_config=config) ``` ### Parameters * `df` (pd.DataFrame): Input DataFrame * `column_name` (str): Column containing JSON tuples * `col_config` (dict): Configuration for key-value mapping * `cols`: Output column names * `look_up`: Input property names ### Returns DataFrame with JSON tuple column split into separate columns *** ## compress\_rows\_to\_col Compresses previously exploded rows back into a single column containing array data. ### Usage ```python theme={null} from gluestick.pandas_utils import compress_rows_to_col # Basic compression df = compress_rows_to_col(df, 'line_items', 'invoice_id') # With CSV storage df = compress_rows_to_col( df, 'line_items', 'invoice_id', use_csv=True ) ``` ### Parameters * `df` (pd.DataFrame): Input DataFrame * `column_prefix` (str): Prefix of columns to compress * `pk` (str): Primary key for grouping rows * `use_csv` (bool): Use CSV format for storage ### Returns DataFrame with specified columns compressed into array format *** ## array\_to\_dict\_reducer Creates a reducer function that converts arrays into dictionaries using specified key-value properties. ### Usage ```python theme={null} from gluestick.pandas_utils import array_to_dict_reducer from functools import reduce # Create reducer reducer = array_to_dict_reducer( key_prop='name', value_prop='value' ) # Apply to array result = reduce(reducer, array_data, {}) ``` ### Parameters * `key_prop` (str): Property to use as dictionary key * `value_prop` (str): Property to use as dictionary value ### Returns Function that reduces arrays to dictionaries ### Notes * Returns a reducer function to be used with functools.reduce * Raises AttributeError if values aren't dictionaries * Handles both specified key-value pairs and full dictionary merging *** ## clean\_obj\_null\_values Replaces null values with None in stringified objects for further processing. ### Usage ```python theme={null} from gluestick.etl_utils import clean_obj_null_values # Clean stringified object cleaned = clean_obj_null_values(json_string) ``` ### Parameters * `obj` (str): Stringified dictionary/list with null values ### Returns String with 'null' values replaced with 'None' ### Notes * Returns empty dict () for pandas NA values * Particularly useful before using explode functions * Preserves original object structure for non-null values ## Common Patterns ### Processing Nested JSON Data ```python theme={null} import gluestick as gs import pandas as pd # Example with nested invoice data def process_invoice_lines(df): # Clean nulls first df['line_items'] = df['line_items'].apply(gs.clean_obj_null_values) # Explode to rows df_lines = gs.explode_json_to_rows(df, 'line_items') # Process and transform # ... apply transformations ... # Compress back to column if needed df = gs.compress_rows_to_col(df_lines, 'line_items', 'invoice_id') return df ``` # Introduction to Gluestick Source: https://docs.hotglue.com/transformation/gluestick/overview A Python library for efficient ETL processes, optimized for hotglue Gluestick is an open source ETL toolkit developed and maintained by hotglue. It is optimized for usage in hotglue pre-processing scripts. The code is available on GitHub and is free to use under the MIT license. > [card] [GitHub Repository](https://github.com/hotgluexyz/gluestick) > > Access the complete source code, contribute, or report issues through our GitHub repository. Star us to show support! ## Getting started with gluestick ```bash theme={null} # Install from PyPI pip install gluestick # Import utilities import gluestick as gs ``` ## Key Features * Robust ETL utilities for data processing * Singer protocol integration * Advanced JSON and object handling * Snapshot management for incremental loads * Production-ready error handling ## File Reading Functions > [card] [Reader](/transformation/gluestick/read-files#reader-recommended) > > RECOMMENDED: Class for reading sync-output data. Provides methods to read directories, get file metadata, and extract primary keys from parquet files. > [card] [read\_csv\_folder](/transformation/gluestick/read-files#read-csv-folder) > > Reads multiple CSV files from a directory, organizing them by entity type based on filename. Supports custom converters and index columns per entity. > [card] [read\_parquet\_folder](/transformation/gluestick/read-files#read-parquet-folder) > > Similar to read\_csv\_folder but for Parquet files. Automatically organizes files by entity type and supports ignoring specific files. > [card] [get\_catalog\_schema](/transformation/gluestick/read-files#get-catalog-schema) > > Retrieves DataFrame schema from Singer catalog. ## Snapshot Management > [card] [snapshot\_records](/transformation/gluestick/snapshots#snapshot-records) > > Manages data snapshots by updating existing snapshots or creating new ones. Supports type coercion and handles both CSV and Parquet formats. > [card] [read\_snapshots](/transformation/gluestick/snapshots#read-snapshots) > > Reads snapshot data for a specific stream from either Parquet or CSV format. Supports additional pandas read options. > [card] [drop\_redundant](/transformation/gluestick/snapshots#drop-redundant) > > Removes duplicate rows based on content hashing. Maintains state of processed data and supports update tracking. ## JSON & Object Handling > [card] [json\_tuple\_to\_cols](/transformation/gluestick/json#json-tuple-to-cols) > > Converts JSON tuple columns into separate columns based on key-value pairs. > [card] [explode\_json\_to\_rows](/transformation/gluestick/json#explode-json-to-rows) > > Explodes array of objects into multiple rows with columns for each object key. > [card] [explode\_json\_to\_cols](/transformation/gluestick/json#explode-json-to-cols) > > Converts JSON array columns into separate columns, with one column per array value. > [card] [compress\_rows\_to\_col](/transformation/gluestick/json#compress-rows-to-col) > > Compresses exploded rows back into a single column with array data. > [card] [array\_to\_dict\_reducer](/transformation/gluestick/json#array-to-dict-reducer) > > Converts arrays into dictionaries using specified key-value properties. > [card] [clean\_obj\_null\_values](/transformation/gluestick/json#clean-obj-null-values) > > Replaces null values with None in stringified objects for further processing. ## Data Transformation > [card] [clean\_convert](/transformation/gluestick/data-transformation#clean-convert) > > Recursively cleans None values from lists and dictionaries. Handles nested structures and datetime conversions. > [card] [map\_fields](/transformation/gluestick/data-transformation#map-fields) > > Maps row values according to a specified mapping dictionary. Supports nested structures and conditional mapping. > [card] [rename](/transformation/gluestick/data-transformation#rename) > > Renames DataFrame columns using JSON format with type conversion support. > [card] [localize\_datetime](/transformation/gluestick/data-transformation#localize-datetime) > > Localizes datetime columns to UTC timezone. Handles both naive and timezone-aware timestamps. > [card] [deep\_convert\_datetimes](/transformation/gluestick/data-transformation#deep-convert-datetimes) > > Transforms all nested datetimes to ISO format recursively. > [card] [exception](/transformation/gluestick/data-transformation#exception) > > Standardized error handling with file logging. Creates consistent error reporting across ETL pipelines. ## Data Export & Error Handling > [card] [to\_export](/transformation/gluestick/export#to-export) > > Exports data to various formats (Singer, Parquet, JSON, JSONL, CSV). Supports schema validation, object stringification, and custom formatting. > [card] [to\_singer](/transformation/gluestick/export#to-singer) > > Exports DataFrame to Singer format with schema validation and type handling. # Polars Dataframe Reader Source: https://docs.hotglue.com/transformation/gluestick/polars/dataframes ## PolarsReader While Lazyframes are more efficient, certain operations can be trickier to implement, For small-data operations, you may be better of using the standard Polars Dataframe with `PolarsReader`: ```python theme={null} import gluestick as gs import polars as pl reader = gs.PolarsReader() TENANT_ID = "TENANT_123" for stream in reader.input_files.keys(): df = reader.get(stream, catalog_types=True) df["tenant_id"] = TENANT_ID gs.to_export(df, stream, "./etl-output", keys=["id"]) ``` # Polars Lazyframe Reader Source: https://docs.hotglue.com/transformation/gluestick/polars/lazyframes ## PLLazyFrameReader A Lazyframe is an abstraction of a dataframe that can stream your data from your sync output, apply relevant transformations, and then writes to your export format without ever loading the entire dataset into memory. ```python theme={null} import gluestick as gs import polars as pl reader = gs.PLLazyFrameReader() TENANT_ID = "TENANT_123" for stream in reader.input_files.keys(): lf = reader.get(stream, catalog_types=True) lf = lf.with_columns( pl.lit(TENANT_ID).alias("tenant_id") ) gs.to_export(lf, stream, "./etl-output", keys=["id"]) ``` # Using Polars in Gluestick Source: https://docs.hotglue.com/transformation/gluestick/polars/overview ## Introduction to Polars [Polars](https://pola.rs/) is a fast, efficient dataframe library designed to work with large datasets with a lower memory footprint compared to pandas. It’s ideal for scenarios where performance and scalability are crucial. However, it is a newer library, so documentation may be sparse. ## PolarsReader and PLLazyFrameReader Classes Gluestick now supports two additional reader classes specifically designed for Polars: 1. **`PolarsReader`**: Reads sync output into Polars Dataframes 2. **`PLLazyFrameReader`**: Reads sync output into Polars Lazyframes Both classes inherit from the base `Reader` class. For more information, see the [Polars docs](https://docs.pola.rs/api/python/stable/reference/index.html). # Snapshotting functions Source: https://docs.hotglue.com/transformation/gluestick/polars/snapshots Both Polars readers support snapshots via the following functions: ## `read_snapshots` The `read_snapshots` function reads a snapshot file for a given stream and returns it as either a Polars DataFrame or Lazyframe. * **Parameters**: * `stream`: The name of the stream to read the snapshot for. For example, 'contacts'. * `snapshot_dir`: The path to the directory where snapshot files are stored. * **Example**: ```python theme={null} # Example usage of read_snapshots reader = PolarsReader() stream_name = 'contacts' snapshot_directory = '/path/to/snapshots' # Read snapshot for the 'contacts' stream snapshot_df = reader.read_snapshots(stream=stream_name, snapshot_dir=snapshot_directory) if snapshot_df is not None: print("Snapshot DataFrame:") print(snapshot_df) else: print("No snapshot available.") ``` ## `snapshot_records` The `snapshot_records` function updates a snapshot file with new data for a given stream and returns a merged Polars DataFrame or Lazyframe. * **Parameters**: * `stream_data`: DataFrame (or Lazyframe) containing the new data to be merged. * `stream`: The name of the stream for the snapshots, e.g., 'contacts'. * `snapshot_dir`: Path to the directory where snapshot files are stored. * `pk`: Primary key(s) to use when merging snapshot; can be a string or a list of strings. * `just_new`: If True, returns just the new data, otherwise returns all merged data. * `use_csv`: If True, saves and reads snapshots in CSV format instead of Parquet. * `overwrite`: If True, overwrites existing snapshot files instead of merging. * **Example**: ```python theme={null} import gluestick as gs # Process only new records reader = gs.PolarsReader() snapshot_directory = '/path/to/snapshots' for stream in eval(str(reader)): # Get new data stream_data = reader.get(stream) # Update snapshot and get merged data merged_df = reader.snapshot_records( stream_data=stream_data, stream=stream, snapshot_dir=snapshot_directory, pk=reader.get_pk(stream), just_new=False, use_csv=False, overwrite=False ) gs.to_export(df, stream, "./etl-output", keys=[reader.get_pk(stream)]) ``` # Data Reading Functions Source: https://docs.hotglue.com/transformation/gluestick/read-files ## Reader **Recommended**: A class for reading ETL files from the sync-output directory. This is the recommended way to read ETL files as it provides consistent error handling and metadata access. ### Installation ```python theme={null} from gluestick.reader import Reader ``` ### Basic Usage ```python theme={null} # Initialize with default directories reader = Reader() # Uses ROOT_DIR/sync-output # Get available streams print(reader) # Shows list of available streams ``` ### Key Methods *** #### get(stream, default=None, catalog\_types=False, \*\*kwargs) Reads the selected file into a pandas DataFrame. ```python theme={null} # Basic reading df = reader.get("users") # Using catalog types df = reader.get("users", catalog_types=True) ``` #### get\_metadata(stream) Retrieves metadata from parquet files. ```python theme={null} metadata = reader.get_metadata("users") # Returns dict of metadata key-value pairs ``` *** #### get\_pk(stream) Gets primary key(s) from parquet file metadata. ```python theme={null} primary_keys = reader.get_pk("users") # Returns list of primary key column names ``` *** ## get\_catalog\_schema Retrieves Singer schema from catalog file. ### Usage ```python theme={null} from gluestick.singer import get_catalog_schema, to_singer # Get schema for specific stream schema = get_catalog_schema("users") # Use schema with Singer export to_singer(df, "users", OUTPUT_DIR, schema=schema) ``` ### Returns Dictionary containing the stream's schema definition ### Notes * Requires `catalog.json` in root directory * Raises exception if stream not found in catalog * Filters schema to include only type and properties * Ensures array types have items dictionary ## Common Patterns ### Iterating through multiple streams ```python etl.py theme={null} import gluestick as gs # iterate through each stream in the input directory reader = gs.Reader() for key in eval(str(reader)): # define a dataframe and apply transformations input_df = reader.get(key, catalog_types=True) input_df["tenant"] = TENANT_ID # define the primary keys (assuming the data is Parquet) key_properties = reader.get_pk(key) # write the data out to the output directory gs.to_export(input_df, key, OUTPUT_DIR, keys=key_properties) ``` # Snapshotting functions Source: https://docs.hotglue.com/transformation/gluestick/snapshots ## snapshot\_records A function for managing data snapshots by updating existing snapshots or creating new ones. Handles both CSV and Parquet formats with support for type coercion. ### Installation ```python theme={null} from gluestick.etl_utils import snapshot_records ``` ### Basic Usage ```python theme={null} # Create or update a snapshot for the users table updated_data = snapshot_records( stream_data, "users", SNAPSHOT_DIR, pk="user_id" ) ``` ### Parameters * `stream_data` (DataFrame): New data to be included in snapshot * `stream` (str): Name of the stream * `snapshot_dir` (str): Directory for storing snapshots * `pk` (str|list): Primary key(s) for deduplication * `just_new` (bool): Adds only new records if True * `use_csv` (bool): Use CSV format instead of Parquet * `coerce_types` (bool): Force snapshot types to match stream\_data * `**kwargs`: Additional pandas read options ### Returns pandas DataFrame containing either complete snapshot or just new records *** ## read\_snapshots Read existing snapshot data into a dataframe. ### Usage ```python theme={null} from gluestick.etl_utils import read_snapshots # Read existing snapshot snapshot_df = read_snapshots( "users", SNAPSHOT_DIR ) ``` ### Parameters * `stream` (str): Name of the stream to read * `snapshot_dir` (str): Directory containing snapshots * `**kwargs`: Additional pandas read options ### Returns pandas DataFrame containing snapshot data, or None if no snapshot exists *** ## drop\_redundant Removes duplicate rows based on content hashing, maintaining a snapshot of processed data. ### Usage ```python theme={null} from gluestick.etl_utils import drop_redundant # Basic deduplication clean_df = drop_redundant( df, "users", OUTPUT_DIR, pk="user_id" ) # Track updated records clean_df = drop_redundant( df, "users", OUTPUT_DIR, pk=["user_id", "email"], updated_flag=True ) ``` ### Parameters * `df` (DataFrame): DataFrame to check for duplicates * `name` (str): Name for snapshot hash file * `output_dir` (str): Directory to save state files * `pk` (str|list): Primary key(s) for state tracking * `updated_flag` (bool): Add flag for new/updated rows * `use_csv` (bool): Use CSV format instead of Parquet ### Returns pandas DataFrame with redundant rows removed *** ## Common Patterns ### Incremental Processing ```python etl.py theme={null} import gluestick as gs # Process only new records reader = gs.Reader() for stream in eval(str(reader)): # Get new data input_df = reader.get(stream) # Combine new data with previously snapshotted data all_records = gs.snapshot_records( input_df, stream, SNAPSHOT_DIR, pk=reader.get_pk(stream) ) row_count = all_records.shape[0] print(f"Total number of records across jobs: {row_count}") ``` # JS/TS Transformation Scripts Source: https://docs.hotglue.com/transformation/javascript-scripts To develop your transformation script in JavaScript or TypeScript, hotglue expects the following to be deployed to your connector's ETL environment: 1. `package.json` 2. Either `etl.js` or `etl.ts` hotglue will first install the dependencies given by your `package.json` with: ```bash theme={null} npm install ``` If your ETL includes a `etl.ts` file, we'll transpile it with: ```bash theme={null} tsc etl.ts --module NodeNext --moduleResolution NodeNext --target ES2022 ``` > Note that we transpile your Typescript file into ES2022 Finally, we'll run the (possibly transpiled) `etl.js` directly with: ```bash theme={null} node etl.js ``` # Overview Source: https://docs.hotglue.com/transformation/overview ## What are transformation scripts? hotglue features a transformation layer that can be used to format the raw output from connectors into a format ingestible by your backend (or wherever you're piping the data to). hotglue supports writing transformation scripts in either Python, JavaScript, or TypeScript. To support your scripts, we recommend using our gluestick package to read, modify, and write data. gluestick is available as both a [Python](/transformation/gluestick/overview) and [NPM](/transformation/gluestick-ts/overview) Package. > [!WARNING] > > To learn how to deploy a script, read [Deploy a script](https://docs.hotglue.com/docs/transformations-overview#deploy-the-script). # Python Transformation Scripts Source: https://docs.hotglue.com/transformation/python-scripts hotglue jobs will work with either a `etl.py` file or a `etl.ipynb`. If you are developing your transformation script as a JupyterLab script, you can develop this script directly in the hotglue UI: ## Start the JupyterLab workspace To edit the transformation script for a connector, you can start a JupyterLab workspace directly from hotglue. Start by opening the settings for the connector you'd like to update. From here, launch the JupyterLab workspace by selecting the Python icon: > [!NOTE] > > Generally, when updating the transformation script you should launch the JupyterLab workspace from the admin view – **not** the tenant view. Launching JupyterLab as a tenant create a custom forked script for that tenant. ![Connector configuration screen](https://files.readme.io/a8632a8-16aa095-Screen_Shot_2022-12-26_at_6.49.33_PM-min.png) Connector configuration screen hotglue will provision a hosted JupyterLab workspace for you to connect to – this may take a few minutes. Once the JupyterLab workspace is provisioned, click the launch button to open your workspace. ![Connector configuration screen](https://files.readme.io/b79c8fb-00ef48d-Screen_Shot_2022-12-26_at_6.47.36_PM-min.png) Connect to JupyterLab workspace You've launched JupyterLab and should see something like the below!  🎉 ![3068](https://files.readme.io/194d16c-Screen_Shot_2021-12-15_at_2.25.46_PM.png "Screen Shot 2021-12-15 at 2.25.46 PM.png") JupyterLab > [!NOTE] > > Note that JupyterLab workspaces will timeout after 30 minutes of inactivity, at which point you'll need to start a new workspace. When your session times out, your script is autosaved. ## Define dependencies The `requirements.txt` file in the root directory is where you can specify any Python modules you wish to use as dependencies. In this example, my `requirements.txt` contains the following: ```shell requirements.txt theme={null} gluestick==1.0.4 numpy==1.16.2 pandas==0.25.3 requests==2.24.0 ``` As mentioned above the [gluestick](https://github.com/hotgluexyz/gluestick) package is developed by the hotglue team and provides utility functions for reading and manipulating CSV files with pandas. Read the [wiki on GitHub](https://github.com/hotgluexyz/gluestick/wiki). The [requests](https://docs.python-requests.org/en/latest/) package can be used to make API requests directly from your transformation script. See the testing `requirements.txt` we created in Jupyter below: ![](https://files.readme.io/17a8a77-Screen_Shot_2021-12-15_at_2.26.26_PM.png "Screen Shot 2021-12-15 at 2.26.26 PM.png") ## Edit the script [](https://docs.hotglue.com/docs/transformations-overview#edit-the-script) Inside the `etl` folder, you will find a file titled `etl.ipynb` containing a [default transformation script](https://github.com/hotgluexyz/recipes/blob/master/src/default.ipynb) ![3068](https://files.readme.io/f530f18-Screen_Shot_2021-12-15_at_2.31.18_PM.png "Screen Shot 2021-12-15 at 2.31.18 PM.png") Default transformation script You can use this as a base to understand how to read data with the `gluestick` package and manipulate it using `pandas`. You can also find more [sample scripts available on GitHub](https://github.com/hotgluexyz/recipes/tree/master/src). ## Deploy the script [](https://docs.hotglue.com/docs/transformations-overview#deploy-the-script) Once you have written your transformation script, you must deploy it using the hotglue tab in Jupyter. ![3068](https://files.readme.io/b1680a8-Screen_Shot_2021-12-15_at_2.34.44_PM.png "Screen Shot 2021-12-15 at 2.34.44 PM.png") Deploy the transformation script Jupyter will prompt you to confirm the deployment as pictured below: ![3068](https://files.readme.io/d554c88-Screen_Shot_2021-12-15_at_2.36.06_PM.png "Screen Shot 2021-12-15 at 2.36.06 PM.png") Confirm transformation script deployment If you do not deploy your script, your changes will be autosaved but will **not** be used. Autosaved transformation scripts can be found in the `cached` folder. ![](https://files.readme.io/fddeac3-7fc9101-Screen_Shot_2022-12-26_at_6.49.12_PM-min.png) > [!NOTE] > > Note that the CLI only downloads the deployed version of the script. If you have a script that is not deployed, you will need to load a Jupyter notebook to deploy your cached edits # Sample Scripts Source: https://docs.hotglue.com/transformation/sample-scripts ## Add some content Learn how to update your docs locally and deploy them to the public. # Snapshots Source: https://docs.hotglue.com/transformation/snapshots What snapshotting is, and how to use it # What is Snapshotting? hotglue's transformation layer allows you to save and persist data across sync jobs for every tenant. This feature is called **snapshotting**. Some use cases include: * storing some metadata about the tenant necessary for the transformation script to run (mapping, an API key/identifier, etc.) * persisting a **state** of the data that this tenant has already synced. For example, you could keep a full copy of all the data the tenant has synced to detect which records are new vs updated. * allowing different integrations to access information about the tenant. For example, you could correlate data across Salesforce and Quickbooks to generate some unified output. # How to use Snapshots? ## Transformation Script [](https://docs.hotglue.com/docs/snapshots#transformation-script) **Note:** this guide assumes you've read the [writing a basic script](https://docs.hotglue.com/docs/writing-a-basic-script) of the docs. As described in the [writing a basic script](https://docs.hotglue.com/docs/writing-a-basic-script#standard-directories) section, one of the standard directories for hotglue transformation scripts is the `snapshots` directory. Any data saved to that directory will be persisted across job runs. Let's walk through a quick sample using pandas: ```python util.py theme={null} import os import pandas as pd def get_snapshot(snapshot_dir, stream): snap_path = f"{snapshot_dir}/{stream}.snapshot.csv" # Ensure file exists if os.path.isfile(snap_path) is False: return None # Read the old snapshot, if present snap_df = pd.read_csv(snap_path) return snap_df def update_snapshot(snapshot_dir, stream, key, data_df, persist=True, override=False, drop_column=None, sort_columns=None, drop_duplicates=True): snap_df = data_df if drop_duplicates: snap_df = snap_df.drop_duplicates(key, keep="last") if not override: # Get the old snapshot dataframe psnap_df = get_snapshot(snapshot_dir, stream) if psnap_df is not None: # Combine with prior snapshot snap_df = snap_df.set_index( key).combine_first(psnap_df.set_index(key)) snap_df = snap_df.reset_index() if drop_column is not None: snap_df = snap_df.drop(columns=drop_column, errors='ignore') if persist: # Save this snapshot in correct spot snap_path = f"{snapshot_dir}/{stream}.snapshot.csv" snap_df.to_csv(snap_path, index=False) if sort_columns is not None: snap_df.sort_values(by=sort_columns) return snap_df ``` The file above defines two functions: * `update_snapshot` is designed to take data new data from a job sync, and append it to any existing snapshot. This will ensure every job run has access to the full history of data that has been synced by this tenant * `get_snapshot` reads the snapshot directory to get the snapshot for the `stream` id passed (you can think of a `stream` as the name of a table) Using the above, we could do the following in our `etl.ipynb` to generate a snapshot of all the `Account` data from an integration (like Quickbooks): ```python etl.ipynb theme={null} import gluestick as gs import pandas as pd import os from lib import util # standard directory for hotglue ROOT_DIR = os.environ.get("ROOT_DIR", ".") INPUT_DIR = f"{ROOT_DIR}/sync-output" OUTPUT_DIR = f"{ROOT_DIR}/etl-output" SNAPSHOT_DIR = f"{ROOT_DIR}/snapshots" # Read input data input_data = gs.read_csv_folder(INPUT_DIR) # Create a snapshot of the Account stream if it is available if input_data.get("Account") is not None: util.update_snapshot( SNAPSHOT_DIR, "Account", ['Id'], input_data["Account"] ) # Get Account snapshot data accounts = util.get_snapshot(SNAPSHOT_DIR, "Account") ``` That's all there is to it! ## API Additionally, you can modify the snapshots on a tenant level [via the API](https://docs.hotglue.com/reference/tenants-delete-snapshot). For example, you could save a tenant `config.json` in the snapshot to store some metadata such as an API key programmatically. ## Managing Snapshots in the UI Snapshots can now be managed directly in the hotglue UI. In addition to the API, you can edit them through the dashboard. Follow the steps below to manage snapshots for a specific tenant: 1. Navigate to the Tenants section from the left-hand navigation menu. ![Go to Tenants](https://mintcdn.com/hotglue/3UEsw-oDLIwEEPsG/images/Go%20to%20Tenants%20\(1\).png?fit=max\&auto=format\&n=3UEsw-oDLIwEEPsG\&q=85\&s=bbf06d13e5e59170cbce0b99da9954bc) 2. Click on the desired tenant. ![Click on the desired tenant](https://mintcdn.com/hotglue/3UEsw-oDLIwEEPsG/images/Click%20on%20the%20desired%20tenant%20\(2\).png?fit=max\&auto=format\&n=3UEsw-oDLIwEEPsG\&q=85\&s=bc394c779202db53396d79b4e29d8699) 3. A slide-in panel will open for the selected tenant. Click on the **Snapshots** tab. ![Click on the Snapshots header](https://mintcdn.com/hotglue/3UEsw-oDLIwEEPsG/images/Click%20on%20the%20Snapshots%20header%20\(3\).png?fit=max\&auto=format\&n=3UEsw-oDLIwEEPsG\&q=85\&s=6b4e1934f1cdbb1df8c88f7dd8e0df4b) 4. Within the Snapshots tab, you can **Upload** new files, **Create folders** to organize them, **Download** existing files, and **Delete** items that are no longer needed — all directly from the UI. ![Snapshots Tab](https://mintcdn.com/hotglue/wqQErWuHjiFi0IHQ/images/Snapshots%20Tab%20\(4\).png?fit=max\&auto=format\&n=wqQErWuHjiFi0IHQ\&q=85\&s=31c20c5605c02446f6b6790d1b0f9764) > [!NOTE] > > Snapshots are created at the tenant level and can only be viewed and managed within that specific tenant. # Custom Params Source: https://docs.hotglue.com/transformation/use-cases/custom-params How to add custom parameters to the hotglue widget # What are Custom Params? hotglue allows you to specify custom parameters that will be collected before a tenant links an integration in the hotglue widget. These parameters are then made available to your transformation script during execution. The screenshot below shows a sample of custom parameters applied to a QuickBooks integration: # Enabling custom params ## Start a JupyterLab workspace To enable custom params, you should first [launch a JupyterLab workspace](https://docs.hotglue.com/docs/transformations-overview#start-the-jupyterlab-workspace). ## Configure the custom params Once inside, you will create an `availableSources.json` which specifies an override for the source you wish to specify custom parameters for. A sample is given below: ```json JSON theme={null} [ { "tap": "quickbooks", "domain": "quickbooks.intuit.com", "label": "QuickBooks", "connect_ui_params": { "invoice_equals_contract": { "label": "Invoice Equals Contract", "description": "RevRec would auto infer the sales order based on invoice if this parameter is True.", "type": "boolean", "required": false }, "use_customer_name_mapping": { "label": "Use Customer Name Mapping", "description": "Use customer name mapping to establish the [Customer Id] from invoices that get loaded to RevRec. This file will be generated by the [Sales] flow.", "type": "boolean", "required": false }, "ignore_items": { "label": "Ignore Items", "description": "Ignore these items from invoices when creating invoices in RevRec", "type": "text", "required": false }, "date_format": { "label": "Date Format", "description": "Date format for the dates in item description", "type": "text", "required": false } } } ] ``` As you can see above, all parameters are listed under the `connect_ui_params` key and have the following options: | Name | Description | | - | - | | `label` | The label shown in the hotglue widget for this parameter | | `description` | The description shown in the hotglue widget for this parameter | | `type` | The type of the parameter. Valid values are: `text`, `password`, `boolean`, `select`, and `list` | | `required` | Whether this parameter is required for connection `true` or `false`, defaults to `false` | ## Deploy the custom params Once you've specified the parameters, you must deploy them to hotglue. To start, verify your `availableSources.json` is in the root directory as shown below: ![3068](https://files.readme.io/65bd7ac-Screen_Shot_2021-12-24_at_2.42.36_PM.png "Screen Shot 2021-12-24 at 2.42.36 PM.png") availableSources.json in JupyterLab Now select the hotglue tab in the toolbar and select **Deploy ETL** ![3068](https://files.readme.io/65bd7ac-Screen_Shot_2021-12-24_at_2.42.36_PM.png "Screen Shot 2021-12-24 at 2.42.36 PM.png") deploy availableSources That's all! Now if you open the hotglue widget, you should see your custom parameters visible there. # How to access the custom params? [](https://docs.hotglue.com/docs/custom-params#how-to-access-the-custom-params) Now that your custom params are configured, you can access the values tenants set in your transformation script. The data will be available in the `config.json` file, here's a sample script: ```python Python theme={null} import os import json # Establish standard directories ROOT_DIR = os.environ.get("ROOT_DIR", ".") INPUT_DIR = f"{ROOT_DIR}/sync-output" OUTPUT_DIR = f"{ROOT_DIR}/etl-output" SNAPSHOT_DIR = f"{ROOT_DIR}/snapshots" # Establish config path config_path = f"{ROOT_DIR}/config.json" # Load the config containing custom params values with open(config_path) as f: config = json.load(f) # config contains the following: # note how the keys here match the keys in the connect_ui_params # { # "invoice_equals_contract": False, # "use_customer_name_mapping": False, # "ignore_items": None # } ``` # Use Cases Source: https://docs.hotglue.com/transformation/use-cases/overview Handle advanced use cases in the transformation scripts Learn how to handle more complex cases with the transformations scripts such as: * pushing data directly to your API * creating and processing custom parameters * dealing with primary keys * dealing with type casting # Typing and Primary Keys Source: https://docs.hotglue.com/transformation/use-cases/typing-and-primary-keys How to handle typing and primary keys with transformation scripts # Overview This guide walks through how to leverage the gluestick `to_singer` function to include typing information in payloads sent to your target, and how to send primary key(s) which can be useful when pushing to databases. # Setup your environment ## Dependencies [](https://docs.hotglue.com/docs/transformations-typing-and-primary-keys#dependencies) The script we will walk through is tested with the following `requirements.txt` – if you have different behavior, verify your dependency versions match. > [!WARNING] > > ### Verify your gluestick version > > Ensure that the gluestick library version is 1.0.9 or greater or the `to_singer` function will not be available! ```txt requirements.txt theme={null} pandas==1.3.5 gluestick==1.0.9 numpy==1.23.1 ``` ## Sample data For this example we will be working with some testing Shopify products data. [Download the CSV here](https://drive.google.com/file/d/1eJw3_PZNCg-ZESFRvYy9LAXOqCSdoGo0/view?usp=sharing) to follow along. ```txt products.csv theme={null} status,published_at,created_at,published_scope,vendor,updated_at,body_html,product_type,tags,options,image,handle,images,template_suffix,title,variants,admin_graphql_api_id,id,_sdc_shop_id,_sdc_shop_name,_sdc_shop_myshopify_domain active,2021-11-11T20:20:41.000000Z,2021-11-11T20:20:41.000000Z,web,Burton,2022-06-14T16:55:15.000000Z,Good snowboard!,Snowboard,,"[{'id': 9466522632412, 'product_id': 7439421898972, 'name': 'Title', 'position': 1, 'values': ['First', 'Second']}]","{'id': 34550913794268, 'position': 1, 'created_at': '2021-11-11T20:20:41.000000Z', 'updated_at': '2021-11-11T20:20:41.000000Z', 'alt': None, 'width': 800, 'height': 800, 'src': 'https://cdn.shopify.com/s/files/1/0602/2755/1452/products/mountain-twin.jpg?v=1636662041', 'variant_ids': [], 'admin_graphql_api_id': 'gid://shopify/ProductImage/34550913794268'}",burton-custom-freestyle-153,"[{'id': 34550913794268, 'position': 1, 'created_at': '2021-11-11T20:20:41.000000Z', 'updated_at': '2021-11-11T20:20:41.000000Z', 'alt': None, 'width': 800, 'height': 800, 'src': 'https://cdn.shopify.com/s/files/1/0602/2755/1452/products/mountain-twin.jpg?v=1636662041', 'variant_ids': [], 'admin_graphql_api_id': 'gid://shopify/ProductImage/34550913794268'}]",,Burton Custom Freestyle 153,"[{'id': 42038020210908, 'title': 'First', 'price': '11.00', 'sku': 'FVR', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'First', 'option2': None, 'option3': None, 'created_at': '2021-11-11T20:20:42.000000Z', 'updated_at': '2022-06-14T16:50:45.000000Z', 'taxable': True, 'barcode': None, 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44131890757852, 'inventory_quantity': -119, 'old_inventory_quantity': -119, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42038020210908'}, {'id': 42038020243676, 'title': 'Second', 'price': '20.00', 'sku': 'SVR', 'position': 2, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Second', 'option2': None, 'option3': None, 'created_at': '2021-11-11T20:20:42.000000Z', 'updated_at': '2022-02-04T21:21:39.000000Z', 'taxable': True, 'barcode': None, 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44131890790620, 'inventory_quantity': 38, 'old_inventory_quantity': 38, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42038020243676'}]",gid://shopify/Product/7439421898972,7439421898972,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,2021-12-29T16:37:42.000000Z,2021-12-29T16:37:41.000000Z,web,hotglue testing 1,2022-01-04T15:07:19.000000Z,,,,"[{'id': 9543985365212, 'product_id': 7504697491676, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,simple-product,[],,simple product,"[{'id': 42247057965276, 'title': 'Default Title', 'price': '55.00', 'sku': 'SMP', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2021-12-29T16:37:41.000000Z', 'updated_at': '2022-01-04T15:06:12.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44341183152348, 'inventory_quantity': 22, 'old_inventory_quantity': 22, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42247057965276'}]",gid://shopify/Product/7504697491676,7504697491676,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:25:58.000000Z,web,hotglue testing 1,2022-01-03T18:35:23.000000Z,,,,"[{'id': 9550358708444, 'product_id': 7510221422812, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,delicate-river,[],,delicate river,"[{'id': 42264406196444, 'title': 'Default Title', 'price': '10.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:25:58.000000Z', 'updated_at': '2022-01-03T18:35:23.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358536626396, 'inventory_quantity': 524, 'old_inventory_quantity': 524, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264406196444'}]",gid://shopify/Product/7510221422812,7510221422812,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:05.000000Z,web,hotglue testing 1,2022-01-28T21:05:27.000000Z,,,,"[{'id': 9550359036124, 'product_id': 7510221684956, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,dawn-violet,[],,dawn violet,"[{'id': 42264406687964, 'title': 'Default Title', 'price': '3.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:05.000000Z', 'updated_at': '2022-01-03T18:40:31.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358537117916, 'inventory_quantity': 69699, 'old_inventory_quantity': 69699, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264406687964'}]",gid://shopify/Product/7510221684956,7510221684956,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:07.000000Z,web,hotglue testing 1,2022-01-03T18:32:36.000000Z,,,,"[{'id': 9550359068892, 'product_id': 7510221717724, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,black-butterfly,[],,black butterfly,"[{'id': 42264406720732, 'title': 'Default Title', 'price': '7.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:07.000000Z', 'updated_at': '2022-01-03T18:32:36.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358537150684, 'inventory_quantity': 550, 'old_inventory_quantity': 550, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264406720732'}]",gid://shopify/Product/7510221717724,7510221717724,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:08.000000Z,web,hotglue testing 1,2022-01-03T19:25:37.000000Z,,,,"[{'id': 9550359101660, 'product_id': 7510221750492, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,bold-firefly,[],,bold firefly,"[{'id': 42264406753500, 'title': 'Default Title', 'price': '10.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:09.000000Z', 'updated_at': '2022-01-03T19:20:36.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358537183452, 'inventory_quantity': 21, 'old_inventory_quantity': 21, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264406753500'}]",gid://shopify/Product/7510221750492,7510221750492,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:10.000000Z,web,hotglue testing 1,2022-01-03T18:35:02.000000Z,,,,"[{'id': 9550359331036, 'product_id': 7510221914332, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,delicate-leaf,[],,delicate leaf,"[{'id': 42264406819036, 'title': 'Default Title', 'price': '7.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:10.000000Z', 'updated_at': '2022-01-03T18:35:02.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358537248988, 'inventory_quantity': 7474, 'old_inventory_quantity': 7474, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264406819036'}]",gid://shopify/Product/7510221914332,7510221914332,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:12.000000Z,web,hotglue testing 1,2022-01-03T18:35:40.000000Z,,,,"[{'id': 9550359363804, 'product_id': 7510221947100, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,divine-star,[],,divine star,"[{'id': 42264406851804, 'title': 'Default Title', 'price': '3.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:12.000000Z', 'updated_at': '2022-01-03T18:35:40.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358537281756, 'inventory_quantity': 886, 'old_inventory_quantity': 886, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264406851804'}]",gid://shopify/Product/7510221947100,7510221947100,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:14.000000Z,web,hotglue testing 1,2022-01-03T19:25:37.000000Z,,,,"[{'id': 9550359494876, 'product_id': 7510222045404, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,broken-grass,[],,broken grass,"[{'id': 42264406950108, 'title': 'Default Title', 'price': '6.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:14.000000Z', 'updated_at': '2022-01-03T19:20:36.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358537380060, 'inventory_quantity': 452, 'old_inventory_quantity': 452, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264406950108'}]",gid://shopify/Product/7510222045404,7510222045404,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:17.000000Z,web,hotglue testing 1,2022-01-03T18:34:08.000000Z,,,,"[{'id': 9550359560412, 'product_id': 7510222110940, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,crimson-darkness,[],,crimson darkness,"[{'id': 42264407015644, 'title': 'Default Title', 'price': '6.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:17.000000Z', 'updated_at': '2022-01-03T18:34:08.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358537445596, 'inventory_quantity': 0, 'old_inventory_quantity': 0, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264407015644'}]",gid://shopify/Product/7510222110940,7510222110940,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:22.000000Z,web,hotglue testing 1,2022-01-03T18:38:51.000000Z,,,,"[{'id': 9550359658716, 'product_id': 7510222209244, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,winter-field,[],,winter field,"[{'id': 42264407113948, 'title': 'Default Title', 'price': '1.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:22.000000Z', 'updated_at': '2022-01-03T18:38:51.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358537543900, 'inventory_quantity': 9, 'old_inventory_quantity': 9, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264407113948'}]",gid://shopify/Product/7510222209244,7510222209244,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:27.000000Z,web,hotglue testing 1,2022-01-03T18:37:03.000000Z,,,,"[{'id': 9550359855324, 'product_id': 7510222340316, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,young-sky,[],,young sky,"[{'id': 42264407343324, 'title': 'Default Title', 'price': '10.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:28.000000Z', 'updated_at': '2022-01-03T18:37:03.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358537773276, 'inventory_quantity': 44, 'old_inventory_quantity': 44, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264407343324'}]",gid://shopify/Product/7510222340316,7510222340316,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:35.000000Z,web,hotglue testing 1,2022-01-03T18:36:05.000000Z,,,,"[{'id': 9550360150236, 'product_id': 7510222569692, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,withered-night,[],,withered night,"[{'id': 42264407671004, 'title': 'Default Title', 'price': '10.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:35.000000Z', 'updated_at': '2022-01-03T18:36:05.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358538100956, 'inventory_quantity': 2, 'old_inventory_quantity': 2, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264407671004'}]",gid://shopify/Product/7510222569692,7510222569692,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:39.000000Z,web,hotglue testing 1,2022-06-13T12:26:51.000000Z,,,,"[{'id': 9550360412380, 'product_id': 7510222733532, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,bitter-grass,[],,bitter grass,"[{'id': 42264408883420, 'title': 'Default Title', 'price': '6.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:39.000000Z', 'updated_at': '2022-06-13T12:26:51.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358539313372, 'inventory_quantity': 47, 'old_inventory_quantity': 47, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264408883420'}]",gid://shopify/Product/7510222733532,7510222733532,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:42.000000Z,web,hotglue testing 1,2022-01-03T18:38:20.000000Z,,,,"[{'id': 9550360510684, 'product_id': 7510222831836, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,wispy-shadow,[],,wispy shadow,"[{'id': 42264409145564, 'title': 'Default Title', 'price': '8.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:42.000000Z', 'updated_at': '2022-01-03T18:38:20.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358539575516, 'inventory_quantity': 15, 'old_inventory_quantity': 15, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264409145564'}]",gid://shopify/Product/7510222831836,7510222831836,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:55.000000Z,web,hotglue testing 1,2022-01-03T18:37:18.000000Z,,,,"[{'id': 9550360871132, 'product_id': 7510223126748, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,young-wood,[],,young wood,"[{'id': 42264409604316, 'title': 'Default Title', 'price': '1.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:55.000000Z', 'updated_at': '2022-01-03T18:37:18.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358540034268, 'inventory_quantity': 33, 'old_inventory_quantity': 33, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264409604316'}]",gid://shopify/Product/7510223126748,7510223126748,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:26:59.000000Z,web,hotglue testing 1,2022-01-03T18:36:22.000000Z,,,,"[{'id': 9550360936668, 'product_id': 7510223192284, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,empty-lake,[],,empty lake,"[{'id': 42264409669852, 'title': 'Default Title', 'price': '6.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:26:59.000000Z', 'updated_at': '2022-01-03T18:36:22.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358540099804, 'inventory_quantity': 66, 'old_inventory_quantity': 66, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264409669852'}]",gid://shopify/Product/7510223192284,7510223192284,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:27:02.000000Z,web,hotglue testing 1,2022-01-28T21:05:27.000000Z,,,,"[{'id': 9550361100508, 'product_id': 7510223323356, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,broken-shadow,[],,broken shadow,"[{'id': 42264409768156, 'title': 'Default Title', 'price': '7.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:27:02.000000Z', 'updated_at': '2022-01-03T18:33:56.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358540198108, 'inventory_quantity': 66, 'old_inventory_quantity': 66, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264409768156'}]",gid://shopify/Product/7510223323356,7510223323356,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:27:04.000000Z,web,hotglue testing 1,2022-01-03T19:25:37.000000Z,,,,"[{'id': 9550361166044, 'product_id': 7510223356124, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,falling-waterfall,[],,falling waterfall,"[{'id': 42264409964764, 'title': 'Default Title', 'price': '3.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:27:04.000000Z', 'updated_at': '2022-01-03T19:22:56.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358540394716, 'inventory_quantity': 49, 'old_inventory_quantity': 49, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264409964764'}]",gid://shopify/Product/7510223356124,7510223356124,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:27:09.000000Z,web,hotglue testing 1,2022-01-03T18:45:36.000000Z,,,,"[{'id': 9550361297116, 'product_id': 7510223487196, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,fragrant-sea,[],,fragrant sea,"[{'id': 42264410095836, 'title': 'Default Title', 'price': '3.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:27:09.000000Z', 'updated_at': '2022-01-03T18:45:36.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358540525788, 'inventory_quantity': 101, 'old_inventory_quantity': 101, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264410095836'}]",gid://shopify/Product/7510223487196,7510223487196,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:27:11.000000Z,web,hotglue testing 1,2022-06-13T12:23:03.000000Z,,,,"[{'id': 9550361329884, 'product_id': 7510223519964, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,autumn-field,[],,autumn field,"[{'id': 42264410128604, 'title': 'Default Title', 'price': '8.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:27:11.000000Z', 'updated_at': '2022-06-13T12:23:03.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358540558556, 'inventory_quantity': 19, 'old_inventory_quantity': 19, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264410128604'}]",gid://shopify/Product/7510223519964,7510223519964,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:27:18.000000Z,web,hotglue testing 1,2022-01-03T19:25:37.000000Z,,,,"[{'id': 9550361559260, 'product_id': 7510223683804, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,winter-violet,[],,winter violet,"[{'id': 42264410390748, 'title': 'Default Title', 'price': '2.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:27:19.000000Z', 'updated_at': '2022-01-03T19:23:32.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358540820700, 'inventory_quantity': 3, 'old_inventory_quantity': 3, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264410390748'}]",gid://shopify/Product/7510223683804,7510223683804,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com active,,2022-01-03T18:27:22.000000Z,web,hotglue testing 1,2022-01-03T18:37:56.000000Z,,,,"[{'id': 9550361723100, 'product_id': 7510223782108, 'name': 'Title', 'position': 1, 'values': ['Default Title']}]",,frosty-darkness,[],,frosty darkness,"[{'id': 42264410783964, 'title': 'Default Title', 'price': '4.00', 'sku': '', 'position': 1, 'inventory_policy': 'deny', 'compare_at_price': None, 'fulfillment_service': 'manual', 'inventory_management': 'shopify', 'option1': 'Default Title', 'option2': None, 'option3': None, 'created_at': '2022-01-03T18:27:22.000000Z', 'updated_at': '2022-01-03T18:37:56.000000Z', 'taxable': True, 'barcode': '', 'grams': 0, 'image_id': None, 'weight': 0.0, 'weight_unit': 'lb', 'inventory_item_id': 44358541213916, 'inventory_quantity': 74, 'old_inventory_quantity': 74, 'requires_shipping': True, 'admin_graphql_api_id': 'gid://shopify/ProductVariant/42264410783964'}]",gid://shopify/Product/7510223782108,7510223782108,60227551452,hotglue testing 1,hotglue-testing-1.myshopify.com ``` # Sample Script ## Typing with pandas First you will need to ensure your pandas dataframe has the correct types when the data is exported to the target. This is generally achieved using the [astype function](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.astype.html) Refer to the sample script below which: * Reads the products CSV as pandas dataframe, * Does some light transformation on the data, and * Casts the types of the columns in the dataframe ```python etl.py theme={null} # Import dependencies import gluestick as gs import pandas as pd import os # Establish standard directories for hotglue ROOT_DIR = os.environ.get("ROOT_DIR", ".") INPUT_DIR = f"{ROOT_DIR}/sync-output" OUTPUT_DIR = f"{ROOT_DIR}/etl-output" # Read input data input_data = gs.read_csv_folder(INPUT_DIR) # Get the products dataframe products = input_data["products"] # Explode the variants column products = gs.explode_json_to_rows(products, "variants") # Create an active flag column that is a boolean products["active"] = products["status"]=="active" # Convert the created_at column to datetime type products["created_at"] = pd.to_datetime(products["created_at"]) # Rename some of the exploded columns names = { "variants.id": "variants_id", "variants.sku": "variants_sku", "variants.price": "price", "variants.title": "variants_title", "variants.inventory_quantity": "inventory_quantity" } products = products.rename(names, axis=1) # Select just the relevant columns products = products[["id", "active", "vendor", "title", "variants_id", "variants_sku", "price", "variants_title", "inventory_quantity", "created_at"]] # Force pandas to use the correct types types = { "id": int, "active": bool, "vendor": "string", "title": "string", "variants_id": int, "variants_sku": "string", "price": float, "variants_title": "string", "inventory_quantity": int, } products = products.astype(types) ``` ## Export the data Now that your dataframe has the types set, we can export the data using the gluestick `to_singer` function. The arguments of the `to_singer` function are: | Argument | Description | | - | - | | `df` | the dataframe to write. In this case, `products` | | `name` | the name of the table, will be used by the target. In this case, `products` | | `dir` | the directory to write the `data.singer` file to. Should always be `OUTPUT_DIR` when using hotglue | | `keys` | an array of primary keys to use for this table | Refer to the sample script below: ```python etl.py theme={null} # Write the data as a data.singer file in the etl-output directory gs.to_singer(products, "products", OUTPUT_DIR, keys=["id", "variants_id"]) ``` This generates the following output ([download here](https://drive.google.com/file/d/1ToAW4PyKGZZiwLQ8xoNRznj2QQE17OyO/view?usp=sharing)) ```json data.singer theme={null} {"type": "SCHEMA", "stream": "products", "schema": {"type": ["object", "null"], "properties": {"id": {"type": ["integer", "null"]}, "active": {"type": ["boolean", "null"]}, "vendor": {"type": ["string", "null"]}, "title": {"type": ["string", "null"]}, "variants_id": {"type": ["integer", "null"]}, "variants_sku": {"type": ["string", "null"]}, "price": {"type": ["number", "null"]}, "variants_title": {"type": ["string", "null"]}, "inventory_quantity": {"type": ["integer", "null"]}, "created_at": {"format": "date-time", "type": ["string", "null"]}}}, "key_properties": ["id", "variants_id"]} {"type": "RECORD", "stream": "products", "record": {"id": 7439421898972, "active": true, "vendor": "Burton", "title": "Burton Custom Freestyle 153", "variants_id": 42038020210908, "variants_sku": "FVR", "price": 11.0, "variants_title": "First", "inventory_quantity": -119, "created_at": "2021-11-11T20:20:41.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7439421898972, "active": true, "vendor": "Burton", "title": "Burton Custom Freestyle 153", "variants_id": 42038020243676, "variants_sku": "SVR", "price": 20.0, "variants_title": "Second", "inventory_quantity": 38, "created_at": "2021-11-11T20:20:41.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7504697491676, "active": true, "vendor": "hotglue testing 1", "title": "simple product", "variants_id": 42247057965276, "variants_sku": "SMP", "price": 55.0, "variants_title": "Default Title", "inventory_quantity": 22, "created_at": "2021-12-29T16:37:41.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510221422812, "active": true, "vendor": "hotglue testing 1", "title": "delicate river", "variants_id": 42264406196444, "variants_sku": "", "price": 10.0, "variants_title": "Default Title", "inventory_quantity": 524, "created_at": "2022-01-03T18:25:58.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510221684956, "active": true, "vendor": "hotglue testing 1", "title": "dawn violet", "variants_id": 42264406687964, "variants_sku": "", "price": 3.0, "variants_title": "Default Title", "inventory_quantity": 69699, "created_at": "2022-01-03T18:26:05.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510221717724, "active": true, "vendor": "hotglue testing 1", "title": "black butterfly", "variants_id": 42264406720732, "variants_sku": "", "price": 7.0, "variants_title": "Default Title", "inventory_quantity": 550, "created_at": "2022-01-03T18:26:07.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510221750492, "active": true, "vendor": "hotglue testing 1", "title": "bold firefly", "variants_id": 42264406753500, "variants_sku": "", "price": 10.0, "variants_title": "Default Title", "inventory_quantity": 21, "created_at": "2022-01-03T18:26:08.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510221914332, "active": true, "vendor": "hotglue testing 1", "title": "delicate leaf", "variants_id": 42264406819036, "variants_sku": "", "price": 7.0, "variants_title": "Default Title", "inventory_quantity": 7474, "created_at": "2022-01-03T18:26:10.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510221947100, "active": true, "vendor": "hotglue testing 1", "title": "divine star", "variants_id": 42264406851804, "variants_sku": "", "price": 3.0, "variants_title": "Default Title", "inventory_quantity": 886, "created_at": "2022-01-03T18:26:12.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510222045404, "active": true, "vendor": "hotglue testing 1", "title": "broken grass", "variants_id": 42264406950108, "variants_sku": "", "price": 6.0, "variants_title": "Default Title", "inventory_quantity": 452, "created_at": "2022-01-03T18:26:14.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510222110940, "active": true, "vendor": "hotglue testing 1", "title": "crimson darkness", "variants_id": 42264407015644, "variants_sku": "", "price": 6.0, "variants_title": "Default Title", "inventory_quantity": 0, "created_at": "2022-01-03T18:26:17.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510222209244, "active": true, "vendor": "hotglue testing 1", "title": "winter field", "variants_id": 42264407113948, "variants_sku": "", "price": 1.0, "variants_title": "Default Title", "inventory_quantity": 9, "created_at": "2022-01-03T18:26:22.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510222340316, "active": true, "vendor": "hotglue testing 1", "title": "young sky", "variants_id": 42264407343324, "variants_sku": "", "price": 10.0, "variants_title": "Default Title", "inventory_quantity": 44, "created_at": "2022-01-03T18:26:27.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510222569692, "active": true, "vendor": "hotglue testing 1", "title": "withered night", "variants_id": 42264407671004, "variants_sku": "", "price": 10.0, "variants_title": "Default Title", "inventory_quantity": 2, "created_at": "2022-01-03T18:26:35.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510222733532, "active": true, "vendor": "hotglue testing 1", "title": "bitter grass", "variants_id": 42264408883420, "variants_sku": "", "price": 6.0, "variants_title": "Default Title", "inventory_quantity": 47, "created_at": "2022-01-03T18:26:39.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510222831836, "active": true, "vendor": "hotglue testing 1", "title": "wispy shadow", "variants_id": 42264409145564, "variants_sku": "", "price": 8.0, "variants_title": "Default Title", "inventory_quantity": 15, "created_at": "2022-01-03T18:26:42.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510223126748, "active": true, "vendor": "hotglue testing 1", "title": "young wood", "variants_id": 42264409604316, "variants_sku": "", "price": 1.0, "variants_title": "Default Title", "inventory_quantity": 33, "created_at": "2022-01-03T18:26:55.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510223192284, "active": true, "vendor": "hotglue testing 1", "title": "empty lake", "variants_id": 42264409669852, "variants_sku": "", "price": 6.0, "variants_title": "Default Title", "inventory_quantity": 66, "created_at": "2022-01-03T18:26:59.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510223323356, "active": true, "vendor": "hotglue testing 1", "title": "broken shadow", "variants_id": 42264409768156, "variants_sku": "", "price": 7.0, "variants_title": "Default Title", "inventory_quantity": 66, "created_at": "2022-01-03T18:27:02.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510223356124, "active": true, "vendor": "hotglue testing 1", "title": "falling waterfall", "variants_id": 42264409964764, "variants_sku": "", "price": 3.0, "variants_title": "Default Title", "inventory_quantity": 49, "created_at": "2022-01-03T18:27:04.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510223487196, "active": true, "vendor": "hotglue testing 1", "title": "fragrant sea", "variants_id": 42264410095836, "variants_sku": "", "price": 3.0, "variants_title": "Default Title", "inventory_quantity": 101, "created_at": "2022-01-03T18:27:09.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510223519964, "active": true, "vendor": "hotglue testing 1", "title": "autumn field", "variants_id": 42264410128604, "variants_sku": "", "price": 8.0, "variants_title": "Default Title", "inventory_quantity": 19, "created_at": "2022-01-03T18:27:11.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510223683804, "active": true, "vendor": "hotglue testing 1", "title": "winter violet", "variants_id": 42264410390748, "variants_sku": "", "price": 2.0, "variants_title": "Default Title", "inventory_quantity": 3, "created_at": "2022-01-03T18:27:18.000000Z"}} {"type": "RECORD", "stream": "products", "record": {"id": 7510223782108, "active": true, "vendor": "hotglue testing 1", "title": "frosty darkness", "variants_id": 42264410783964, "variants_sku": "", "price": 4.0, "variants_title": "Default Title", "inventory_quantity": 74, "created_at": "2022-01-03T18:27:22.000000Z"}} {"type": "STATE", "value": {}} ``` # Writing a basic script Source: https://docs.hotglue.com/transformation/writing-a-basic-script This guide walks through writing a basic python transform script using the gluestick package ## Before you start This guide assumes you have already launched a JupyterLab workspace, as described in the [Transformations Overview](transformations/python-scripts#start-the-jupyterlab-workspace). ## Environment variables [](https://docs.hotglue.com/docs/writing-a-basic-script#environment-variables) There are several environment variables that will be available when a transformation script runs in hotglue during a job: | Environment Variable | Description | | - | - | | `TENANT` | ID of the tenant (`test-user`) | | `FLOW` | ID of the flow (`FZev7QqK-`) | | `ENV_ID` | ID of the hotglue environment (`prod.hg.example.com`) | | `JOB_ID` | ID of the job (`ZVonkl`) | | `EXTERNAL_JOB_ID` | External ID of the job (`order-123`) | | `API_KEY` | Environment API key (`XXXX`) | | `API_URL` | URL of the hotglue API (`https://api.hotglue.com`) | | `JOB_ROOT` | A unique key marking the root directory for the job (`cust_1/flows/FZev7QqK-/jobs/2024/07/4/25/17/ZVonkl`) | | `SYNC_TYPE` | Type of sync (`incremental_sync`, `auto_sync`, or `full_sync`) | | `JOB_TYPE` | Type of the job, in V2 flows (`write` or `read`) | | `CONNECTOR_ID` | ID of the connector, in V2 flows (`salesforce`) | | `TAP` | The connector managing the sync process, in both V1 and V2 flows (`api`) | | `TARGET` | The connector managing the export, in both V1 and V2 flows (`salesforce`) | You can also add custom env variables for used in your scripts in your [environment settings](https://docs.hotglue.com/environment-settings/environment-variables). You can then reference any env variable in your script using `os.environ`: ```python Python theme={null} import os tenant_id = os.environ.get("TENANT") ``` ## Standard directories [](https://docs.hotglue.com/docs/writing-a-basic-script#standard-directories) In hotglue, there are three **standard** directories: | Directory Path | Description | | - | - | | `sync-output` | This directory contains all **input** data from the data source (typically Parquet or CSV). | | `snapshots` | This directory can be used to store (snapshot) any data for the current tenant. It also stores the `tenant-config.json` used for tenant-specific settings. (typically JSON, Parquet, or CSV). | | `etl-output` | This directory is where you should put all **output** data, formatted as needed for the target your flow is using (typically a data.singer file). | ## The Working Directory When hotglue executes your ETL script, it provides a structured working directory with all the necessary files and data for your transformation. You should reproduce this directory structure when developing scripts locally. ### Directory Structure Overview ``` ROOT/ ├── sync-output/ │ ├── streamone.csv │ └── streamtwo.csv ├── snapshots/ │ ├── streamone.csv │ ├── streamtwo.csv │ └── tenant-config.json ├── etl-output/ │ └── (where output will be written) ├── entry file (either etl.py, etl.ipynb, etl.js, etl.ts) ├── any other files or folders you deploy ├── catalog.json ├── source-config.json ├── target-config.json ├── target-catalog.json (Only available in bidrectional write jobs) ├── source-state.json └── state.json ``` #### 📄 **Configuration Files** The key JSON configuration files available at runtime by your ETL script are: * **catalog.json** - Schema catalog for the data * **source-config.json** - Source system credentials and configuration * **target-config.json** - Target system credentials and configuration * **target-catalog.json** - Target schema catalog (V2 write jobs only) * **source-state.json** - Incremental sync state and bookmarks * **state.json** - Current job execution state You can access these files with: ```python theme={null} import json import os config_path = f"./source-config.json" if os.path.exists(config_path): with open(config_path) as f: config = json.load(f) ``` The `tenant-config.json`, on the other hand, is accessed from the snapshots directory. If you need to read or modify this object, your code will look something like below: ```python theme={null} import json import os SNAPSHOT_DIR = f"{ROOT_DIR}/snapshots" tenant_config_path = f"{SNAPSHOT_DIR}/tenant-config.json" tenant_config= None if os.path.exists(tenant_config_path): with open(tenant_config_path) as f: tenant_config = json.load(f) ``` ## Example: Read the data To start, we will import pandas and the gluestick Python package, and establish the standard input/output directories above. Note:`snapshots` are optional, and may not be needed for your scripts. ```python etl.ipynb theme={null} import gluestick as gs import pandas as pd import os # standard directory for hotglue ROOT_DIR = os.environ.get("ROOT_DIR", ".") INPUT_DIR = f"{ROOT_DIR}/sync-output" OUTPUT_DIR = f"{ROOT_DIR}/etl-output" SNAPSHOT_DIR = f"{ROOT_DIR}/snapshots" ``` My `sync_output` folder contains a CSV file called `campaigns`. Learn more how to get sample data in the [Debugging a script](https://docs.hotglue.com/docs/debugging-a-script) section. ![3068](https://files.readme.io/a45c8e6-Screen_Shot_2021-12-15_at_3.10.05_PM.png "Screen Shot 2021-12-15 at 3.10.05 PM.png") Now we can go ahead and read the data in `INPUT_DIR` with gluestick's [reader](https://github.com/hotgluexyz/gluestick/blob/master/gluestick/etl_utils.py) function. ```python etl.ipynb theme={null} # Read input data input_data = gs.reader() ``` Gluestick automatically parses out the timestamp in the CSV name, so we can access the `campaigns` data as follows: ```python etl.ipynb theme={null} # Get the campaigns data campaigns = input_data.get("campaigns") campaigns.head() ``` By calling `campaigns.head()` we can preview the data ![2218](https://files.readme.io/496ec12-Screen_Shot_2021-12-15_at_3.14.18_PM.png "Screen Shot 2021-12-15 at 3.14.18 PM.png") ## Manipulate the data Now that you have the data as a pandas DataFrame, you can do any transformations you need to. For this example, we will select a few of the columns: `id`, `emails_sent`, `create_time`, and `status`, and then rename them. ```python etl.ipynb theme={null} # Select the columns we want campaigns = campaigns[['id', 'emails_sent', 'create_time', 'status']] # Rename the columns campaigns = campaigns.rename(columns={ 'id': "Id", 'emails_sent': "Sent", 'create_time': "CreatedAt", 'status': "Status" }) campaigns.head() ``` This generates the final output below. You can see [samples of more complex use cases on GitHub](https://github.com/hotgluexyz/recipes) and refer to the [pandas documentation](https://pandas.pydata.org/docs/reference/frame.html). ![2236](https://files.readme.io/f4d1b4c-Screen_Shot_2021-12-15_at_3.20.24_PM.png "Screen Shot 2021-12-15 at 3.20.24 PM.png") ## Write the output data Finally, we can write the output to the standard `OUTPUT_DIR` using pandas `to_csv` function: ```python etl.ipynb theme={null} # Write the output campaigns.to_csv(f"{OUTPUT_DIR}/campaigns.csv", index=False) ``` This generates the output as a CSV file in the `etl-output` directory: ![3068](https://files.readme.io/1009aee-Screen_Shot_2021-12-15_at_3.22.05_PM.png "Screen Shot 2021-12-15 at 3.22.05 PM.png") If you want to write this data to a non-filestore target, such as a database, CRM, or any other standard Singer target, you can use Gluestick's `to_singer` function in lieu of `to_csv`: ```python etl.ipynb theme={null} # Write the output gs.to_singer(campaigns, "Campaigns", OUTPUT_DIR, keys=["Id"]) ``` # Accounting Schema Source: https://docs.hotglue.com/unified-schema/accounting ## Add some content Learn how to update your docs locally and and deploy them to the public. # CRM Schema Source: https://docs.hotglue.com/unified-schema/crm ## Add some content Learn how to update your docs locally and and deploy them to the public. # Custom Plugins Source: https://docs.hotglue.com/unified-schema/custom-plugins Adjust unified schema output with small Python plugins that run before each table is exported ## What are custom plugins? Custom plugins let you change what a unified schema connector exports without replacing its transformation script. A plugin is a Python file that receives one unified table as a pandas DataFrame just before hotglue exports it. It returns the DataFrame, with any changes you made. Common uses include: * Adding a column, such as a tenant-specific label * Removing rows that a tenant does not want to sync * Filling in a default value from the connector's configuration * Changing the primary keys sent with the exported table > [!NOTE] > > The **Custom Plugins** tab is only shown for connectors that use the [unified schema](/unified-schema/introduction), and only when custom plugins are enabled for your organization. Contact hotglue support if you don't see the tab. ## How plugins run When a job runs, hotglue downloads the connector's plugins into a `plugins` folder beside the transformation script. Each time the unified script exports a table, it looks for a plugin named after that table and calls the plugin's `main` function: ``` sync-output → unified mapping → Accounts DataFrame → plugins/Accounts_post_process.py → etl-output ``` * A plugin runs **after** the source data has been mapped to the unified model, and **before** the table is written to `etl-output`. * A table without a matching plugin is exported unchanged. * If a plugin raises an error, the export stops and the job fails with `ETL_FAILED`. The error appears in the job logs. ## Name the plugin file Name each plugin `{Table}_post_process.py`, where `{Table}` is the unified table name, such as `Accounts`, `Vendors`, or `Bills`. One file handles one table. ## Write the `main` function Each plugin must define a top-level `main` function with exactly this signature: ```python theme={null} def main(context, df, model, key_properties, tenant_config={}): ... return df, model, key_properties ``` hotglue checks this signature when you upload or save the file. Type annotations are allowed, but the parameter names, their order, and the `tenant_config={}` default must match. ### Arguments | Argument | Description | | - | - | | `context` | A dictionary with job details and paths. See [Context](#context). | | `df` | A pandas DataFrame with the table's unified records. | | `model` | The unified Pydantic model used to build the exported schema. | | `key_properties` | The table's primary keys, such as `["id", "subsidiaryId"]`. | | `tenant_config` | The tenant's [`tenant-config.json`](/api-reference/manage-tenants/set-tenant-config), or `{}` if the tenant has none. | ### Return value `main` must return a tuple of three values: `(df, model, key_properties)`. * `df` must be a pandas DataFrame. Returning `None` or a DataFrame on its own fails the job. * Return `model` and `key_properties` unchanged unless you want to change them. The values you return are used for the export. * If you add columns to `df`, hotglue adds them to the exported schema as optional fields. You don't need to change `model`. ### Context | Key | Value | | - | - | | `ROOT_DIR` | The job's working directory. Configuration files are in this directory. | | `INPUT_DIR` | `{ROOT_DIR}/sync-output` | | `OUTPUT_DIR` | The directory the table is exported to, usually `{ROOT_DIR}/etl-output` | | `SNAPSHOT_DIR` | `{ROOT_DIR}/snapshots` | | `tenant_id` | The ID of the tenant the job is running for | | `flow_id` | The ID of the flow | ## Read configuration files A plugin can read the same configuration files as a [transformation script](/transformation/writing-a-basic-script#the-working-directory). Build paths from `context["ROOT_DIR"]` and `context["SNAPSHOT_DIR"]`: | File | Contents | Available | | - | - | - | | `tenant-config.json` in `SNAPSHOT_DIR` | The tenant config. Also passed to `main` as `tenant_config`. | When the tenant has a tenant config | | `source-config.json` in `ROOT_DIR` | Settings and custom params of the source. In a read job, this is the connector's config. | Read and write jobs | | `target-config.json` in `ROOT_DIR` | Settings of the target. In a write job, this is the connector's config. | Write jobs, and read jobs whose flow has a target | | `config.json` in `ROOT_DIR` | The connector's own config: the same file as `source-config.json` in a read job and `target-config.json` in a write job. | Read and write jobs | These files can contain credentials. Don't print or log their values. Always check that a file exists before you read it. This lets the same plugin run in both read and write jobs. ## Examples ### Return the table unchanged The smallest valid plugin. ```python Accounts_post_process.py theme={null} def main(context, df, model, key_properties, tenant_config={}): return df, model, key_properties ``` ### Add a column from the tenant config This plugin reads `region` from the tenant config and adds it to every account as a new `tenantRegion` column. The new column is added to the exported schema automatically. ```python Accounts_post_process.py theme={null} def main(context, df, model, key_properties, tenant_config={}): df["tenantRegion"] = tenant_config.get("region") return df, model, key_properties ``` With the tenant config `{"region": "EMEA"}`, every exported account has `"tenantRegion": "EMEA"`. ### Read the tenant config file from snapshots `tenant_config` contains the same data as `tenant-config.json`. You can also read the file directly, which is useful when you reuse code from your transformation scripts: ```python Accounts_post_process.py theme={null} import json import os def main(context, df, model, key_properties, tenant_config={}): path = os.path.join(context["SNAPSHOT_DIR"], "tenant-config.json") if os.path.exists(path): with open(path) as f: hidden_ids = json.load(f).get("hidden_account_ids", []) df = df[~df["id"].isin(hidden_ids)] return df, model, key_properties ``` ### Use `config.json` and change the primary keys `config.json` is always the connector's own config, in both read and write jobs. This plugin adds the connector's `company_id` setting as a column and makes it part of the primary key: ```python Accounts_post_process.py theme={null} import json import os def main(context, df, model, key_properties, tenant_config={}): path = os.path.join(context["ROOT_DIR"], "config.json") if not os.path.exists(path): return df, model, key_properties with open(path) as f: config = json.load(f) df["companyId"] = config.get("company_id") return df, model, [*key_properties, "companyId"] ``` ## Upload and manage plugins ### In the dashboard 1. Open your flow and select the connector. 2. Select the **Custom Plugins** tab. 3. Click **Upload**, or drag `.py` files into the tab, then click **Upload** again to save them. Click a plugin to view or edit it in the browser, then click **Save**. Only Developers and Admins can upload, edit, or delete a plugin. ### With the API The plugin endpoints use your environment's API key in the `x-api-key` header. Use `default` as the tenant to manage the plugins shared by every tenant. Use `connectors` as the entity type for v2 flows, and `taps` for v1 flows. ``` https://api.hotglue.com/{env_id}/{flow_id}/{tenant}/{entity_type}/{connector_id}/etl/plugins ``` ```shell Upload theme={null} curl --request POST \ --url 'https://api.hotglue.com/{env_id}/{flow_id}/default/connectors/{connector_id}/etl/plugins' \ --header 'x-api-key: ' \ --form 'Accounts_post_process.py=@Accounts_post_process.py' ``` ```shell List theme={null} curl --request GET \ --url 'https://api.hotglue.com/{env_id}/{flow_id}/default/connectors/{connector_id}/etl/plugins' \ --header 'x-api-key: ' ``` ```shell Read theme={null} curl --request GET \ --url 'https://api.hotglue.com/{env_id}/{flow_id}/default/connectors/{connector_id}/etl/plugins?file=Accounts_post_process.py' \ --header 'x-api-key: ' ``` ```shell Replace theme={null} curl --request PUT \ --url 'https://api.hotglue.com/{env_id}/{flow_id}/default/connectors/{connector_id}/etl/plugins' \ --header 'x-api-key: ' \ --header 'Content-Type: application/json' \ --data '{"filename": "Accounts_post_process.py", "content": "def main(context, df, model, key_properties, tenant_config={}):\n return df, model, key_properties\n"}' ``` ```shell Delete theme={null} curl --request DELETE \ --url 'https://api.hotglue.com/{env_id}/{flow_id}/default/connectors/{connector_id}/etl/plugins' \ --header 'x-api-key: ' \ --header 'Content-Type: application/json' \ --data '{"file": "Accounts_post_process.py"}' ``` > [!WARNING] > > When you upload with the API, hotglue uses the multipart **field name** as the plugin's file name. Name each form field after its file, as in `--form 'Accounts_post_process.py=@Accounts_post_process.py'`. A generic field name such as `--form 'file=@Accounts_post_process.py'` is rejected. Calling `DELETE` with an empty body (`{}`) deletes **all** plugins for the connector and tenant. # E-Commerce Schema Source: https://docs.hotglue.com/unified-schema/e-commerce ## Add some content Learn how to update your docs locally and and deploy them to the public. # Introduction Source: https://docs.hotglue.com/unified-schema/introduction Learn how the unified schema works and how to use it. ## Description hotglue offers a common schema to help standardize your data and enable you to create integrations faster. Instead of configuring every connector with scripts and field maps, hotglue unified schemas send and receive data in the same format, no matter the connector. This can be helpful if you want to build many integrations quickly, or if your development resources are limited. For those who find this standardization limiting, you may want to check out [transformation scripts](https://docs.hotglue.com/docs/transformations-overview) instead. You can find a complete list of compatible connectors in our [unified schema docs](https://hotglue.com/docs/unified). ## Usage ### 1. Turn on the unified schema Select a [compatible connector](https://hotglue.com/docs/unified). Under **configuration**, click the **unified schema toggle**. > [!NOTE] > > If you don't see the unified schema toggle, make sure your selected connector is compatible. ![](https://files.readme.io/c7c8cf3-Screen_Shot_2022-12-08_at_4.50.34_PM.png) Click 'confirm' to delete your existing script and field map and turn on unified schema ### 2. Configure your schema Click "Customize unified schema objects" to select which tables you would like to sync. Each selected table will include all of the fields as marked in the [docs](https://hotglue.com/docs/unified). Once the unified schema is turned on, your connector configuration gets a lot simpler! You can still manage triggers, but the script and field mapping will now be done for you. # Vanilla JS Setup Source: https://docs.hotglue.com/widget-v3/javascript Using the Widget as a CDN installation You can install the hotglue widget via the following CDN distribution: ```html theme={null} ``` Next, you can initialize the widget using your hotglue [environment ID](/api-reference/overview#environment-id) and [public API key](/api-reference/overview#api-key): ```html theme={null} Hotglue Widget ``` For custom validation before credentials are submitted in React, call the `setCredentialsValidator` handler returned by `useHotglue`. See the full [setCredentialsValidator](/widget-v3/reference/setCredentialsValidator) reference. Finally, you can open the widget `hotglue.openWidget()` ```html theme={null} Hotglue Widget ``` # Overview Source: https://docs.hotglue.com/widget-v3/overview The hotglue widget allows you to offer native, inline integrations in your app with only a few lines of code. # Introduction to the widget The hotglue widget is a white-labeled JavaScript component set for your users to link to hotglue integrations, without leaving your app. ![](https://mintcdn.com/hotglue/dDkA3NAp86Na-aY4/widget-v3/images/widgetDemo.gif?s=e353757c53d4b2f3ecf6281617f46e05) The customizable pop-up widget can be opened from anywhere in your app ![](https://mintcdn.com/hotglue/dDkA3NAp86Na-aY4/widget-v3/images/ConnectionsDemo.png?fit=max\&auto=format\&n=dDkA3NAp86Na-aY4\&q=85\&s=2dfc645b2fb0324e897fefe6ca6bc05b) The inline Connections Component can be used in React apps In addition to providing components, the widget library exposes client side functions for common hotglue tasks you can bake into your UI: ```javascript theme={null} ``` # React Setup Source: https://docs.hotglue.com/widget-v3/react Using the Widget with React You can install the hotglue widget via npm: ```bash theme={null} npm i @hotglue/widget@beta ``` Next, you can pass your [environment ID](/api-reference/overview#environment-id) and [public API key](/api-reference/overview#api-key) into the `useHotglue` hook to initialize the SDK and access the various functions: ```jsx theme={null} const { openWidget, setListeners, link, unlink, relink, runJob, getJobStatus, setLocalization, setTenantMetadata, setCredentialsValidator, } = useHotglue({ tenantId: "", environmentId: "", apiKey: "", }); setCredentialsValidator<{ api_key: string }>(async (oldConfig, newConfig) => { if (!newConfig.api_key) { return { success: false, errorMessage: "API key is required", }; } return { success: true }; }); ``` For custom validation before credentials are submitted, call `setCredentialsValidator`. The generic passed to `setCredentialsValidator()` types `oldConfig` and `newConfig` in the validator. See the full [setCredentialsValidator](/widget-v3/reference/setCredentialsValidator) reference. To skip credential reuse for specific flows, pass [`skipCredentialsReuseFlows`](/widget-v3/reference/skipCredentialsReuseFlows) to `useHotglue`. ## Using the Widget To allow the hotglue Widget to render in your DOM, you can include the `` component anywhere in a mounted component: ```jsx theme={null} import { useHotglue, Widget } from "@hotglue/widget"; export default function WidgetLauncher() { const tenantId = "MY-TENANT-ID"; const { openWidget } = useHotglue({ tenantId, environmentId: process.env.NEXT_PUBLIC_HOTGLUE_ENV_ID, apiKey: process.env.NEXT_PUBLIC_HOTGLUE_PUBLIC_KEY, jwtToken: '' }); return (
); } ``` ## Using the Connections Component You can additionally render the inline Connections component with ``: ```jsx theme={null} import { useHotglue, Widget, Connections } from "@hotglue/widget"; export default function WidgetLauncher() { useHotglue({ tenantId: "MY-TENANT-ID", environmentId: process.env.NEXT_PUBLIC_HOTGLUE_ENV_ID, apiKey: process.env.NEXT_PUBLIC_HOTGLUE_PUBLIC_KEY, jwtToken: '' }); return (
); } ``` ## Using the widget with Tailwind CSS or similar frameworks If you’re using the widget alongside a CSS framework like **Tailwind CSS**, its base reset styles (Preflight) may affect the widget’s appearance.\ To ensure the widget’s styles are applied correctly, import its stylesheet manually in your global CSS file: ```css theme={null} /* globals.css */ @import "@hotglue/widget/dist/widget-react.css"; ``` # Connections Source: https://docs.hotglue.com/widget-v3/reference/connections Render the Connections component ## Connections The `Connections` component is a React component used to render the supported connectors directly within in your application. ### Props: * **flows**: `boolean` * If true, groups the icons by flows. * **className**: `string` (optional) * Overrides the default classes of the connections container. * **hideBackButtons**: `boolean` (optional) * If true, hides back navigation buttons during the connection flow. See [hideBackButtons](/widget-v3/reference/hideBackButtons) for all supported surfaces. * **filter**: `object` (optional) * Allows for filtering to show specific connectors or flows. * **connectors**: `Array` (optional) * An array of connector identifiers to filter. * **flows**: `Array` (optional) * An array of flow identifiers to filter. ![](https://mintcdn.com/hotglue/efi-P21q_Uweg2f5/widget-v3/images/ConnectionsNoGroup.png?fit=max\&auto=format\&n=efi-P21q_Uweg2f5\&q=85\&s=b00e668737a3880079b966ac0de29907) ![](https://mintcdn.com/hotglue/efi-P21q_Uweg2f5/widget-v3/images/ConnectionsByFlow.png?fit=max\&auto=format\&n=efi-P21q_Uweg2f5\&q=85\&s=96b0ba01b5492c1ebd4cc263251ed383) The flows prop determines if the connector components are grouped by flows ### Example: ```jsx theme={null} ```