Skip to Content
LoadersCreating a Loader

Creating a Loader

This guide walks you through setting up a new loader in Zeotap. A loader connects to a SaaS application, extracts data from selected objects, and writes it into your data warehouse on a recurring schedule.

Prerequisites

Before creating a loader, ensure you have:

  • A Zeotap workspace with appropriate permissions (Owner, Admin, or a role with loaders:create permission)
  • A configured Warehouse (the target warehouse where loader data will be written)
  • Credentials for the SaaS application you want to connect (OAuth access or API key)
  • Write permissions on the target schema in your warehouse

Step-by-Step Guide

Step 1: Navigate to Loaders

  1. Log in to your Zeotap workspace
  2. Click Loaders in the left sidebar
  3. Click the Add Loader button in the top-right corner

Step 2: Select the Source Application

Choose the SaaS application you want to pull data from. Zeotap supports 15+ connectors across CRM, marketing, advertising, payments, support, and productivity categories.

Each card shows a short description of the connector; hover over it (or focus it with the keyboard) to read the full text. Once you pick a connector, its full description is shown at the top of the configuration step.

Each connector has its own authentication flow and available objects. See the individual connector guides for detailed setup instructions.

Step 3: Authenticate

Depending on the connector, you’ll authenticate using one of the following methods:

MethodFlowConnectors
OAuth 2.0Click “Connect” and authorize via the application’s login page. Zeotap handles token storage and refresh.Salesforce, HubSpot, Google Ads, Facebook Ads, LinkedIn Ads, Shopify, Intercom, GitHub, Slack
API KeyPaste your API key or secret directly into the configuration form.Stripe, HubSpot (alternative), Zendesk
OAuth 2.0 Client CredentialsProvide your client ID and client secret. Zeotap exchanges them for an access token.Marketo
API TokenProvide a personal or workspace API token along with your account identifier.Zendesk, Jira
Personal Access Token (PAT)Generate a token in the application’s developer settings and paste it into Zeotap.GitHub (alternative), Jira (alternative)

All credentials are encrypted at rest using AES-256 encryption.

Step 4: Discover and Select Objects

After authentication, Zeotap discovers the available objects and streams from the connected application. You’ll see a list of all available objects with metadata:

  • Object name — The API name of the object (e.g., Contact, deals, charges)
  • Record count — Estimated number of records (when available from the API)
  • Cursor field — The field used for incremental sync (e.g., updated_at, SystemModstamp); a stream without one is read in full every run

Select the objects you want to sync. You don’t need to select everything — choose only the objects that are relevant to your use case to minimize API usage and warehouse storage.

For each selected object, you can:

  • Choose its sync mode — Full refresh, Append or Merge. The select is pre-filled with the connector’s recommendation for that object where it has one, and with the loader’s Default sync mode otherwise. Changing the default offers Apply to all streams. The form warns if you choose Append for a stream with no cursor, because every run would add another full copy of it. See Sync mode per stream.
  • Set the merge key — For a stream in Merge mode, specify which field(s) uniquely identify a record, overriding the key the connector declares

Step 5: Configure the Target Warehouse

Specify where loader data should be written:

SettingDescriptionExample
Target WarehouseThe warehouse connection to write intoProduction Snowflake
Target SchemaThe schema where tables will be createdSALESFORCE_RAW
Table PrefixOptional prefix for all table names created by this loadersf_

Zeotap creates tables automatically. If a table already exists, the loader replaces, appends to or merges into it according to that stream’s sync mode.

Step 6: Configure the Schedule

Set the sync frequency:

IntervalBest For
Every 15 minutesCritical operational data (e.g., support tickets, orders)
HourlyGeneral-purpose, balances freshness with API efficiency
Every 6 hoursOperational data that doesn’t need real-time freshness
DailyReference data, large full-refresh tables, cost-sensitive workloads
Custom cronAdvanced scheduling needs (e.g., 0 2 * * 1-5 for weekday 2 AM runs)

All schedules are evaluated in UTC. You can also choose to leave the schedule paused and trigger runs manually.

Step 7: Name and Save

Give your loader a descriptive name (e.g., “Salesforce Production” or “Stripe Payments”) and click Save.

Zeotap will:

  1. Create the target tables in your warehouse
  2. Run an initial full sync to backfill historical data
  3. Begin the recurring schedule for incremental syncs

The initial sync may take longer depending on data volume. You can monitor progress from the loader’s detail page.

Using the API

You can create loaders programmatically with the Loaders API. Paths are workspace-scoped, and requests need the Authorization and X-Workspace-ID headers described in Authentication.

First list the streams the credentials can read, with each stream’s cursor, key and recommended sync mode:

curl -X POST https://agentic.zeotap.com/api/v1/workspaces/{id}/loaders/discover \ -H "Authorization: Bearer $API_TOKEN" \ -H "X-Workspace-ID: <workspace-id>" \ -H "Content-Type: application/json" \ -d '{ "loader_type": "stripe", "config": {}, "credentials": {"secret_key": "<your Stripe secret key>"} }'

Then create the loader with the streams you want:

curl -X POST https://agentic.zeotap.com/api/v1/workspaces/{id}/loaders \ -H "Authorization: Bearer $API_TOKEN" \ -H "X-Workspace-ID: <workspace-id>" \ -H "Content-Type: application/json" \ -d '{ "name": "Stripe Payments", "loader_type": "stripe", "source_id": "770e8400-e29b-41d4-a716-446655440000", "config": {}, "credentials": {"secret_key": "<your Stripe secret key>"}, "target_schema": "STRIPE_RAW", "selected_streams": ["customers", "charges"], "sync_mode": "incremental", "stream_sync_modes": {"customers": "incremental_merge"}, "primary_keys": {"customers": ["id"]}, "schedule": "0 * * * *" }'
FieldMeaning
selected_streamsStream names, exactly as discovery returns them
sync_modeThe loader’s default sync mode: full_refresh, incremental (append) or incremental_merge (merge on key)
stream_sync_modesModes for streams that differ from sync_mode. Omit it to get the connector’s recommended mode for each selected stream; send it to choose them yourself
primary_keysOptional merge keys per stream, overriding the connector’s
scheduleA cron expression in UTC; omit it to run only on demand

For OAuth connectors (Salesforce, HubSpot, Google Ads, …), complete the connect flow in the UI or through the OAuth endpoints and send "credentials": {"credential_ref": "<ref>"} with the reference it returns.

The response is 201 Created with the stored loader. Its stream_sync_modes holds the per-stream modes that were saved — here {"customers": "incremental_merge"}, so charges appends under the loader’s incremental default:

{ "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Stripe Payments", "loader_type": "stripe", "target_schema": "STRIPE_RAW", "selected_streams": ["customers", "charges"], "sync_mode": "incremental", "stream_sync_modes": {"customers": "incremental_merge"}, "primary_keys": {"customers": ["id"]}, "change_detection": {}, "schedule": "0 * * * *", "status": "draft", "created_at": "2026-10-02T11:00:00Z" }

A new loader is saved as draft. Its schedule starts firing once a connection test (POST …/loaders/{loaderId}/test) succeeds and marks it active; you can trigger a run at any time with POST …/loaders/{loaderId}/trigger.

Managing Loaders

Editing a Loader

To modify an existing loader:

  1. Navigate to Loaders in the sidebar
  2. Click on the loader you want to edit
  3. Modify objects, schedule, or target configuration
  4. Click Save

Adding new objects triggers a backfill for those objects. Removing objects does not delete the corresponding warehouse tables — you must drop them manually if desired.

Pausing and Resuming

You can pause a loader to temporarily stop scheduled runs without losing cursor state. Click Pause on the loader’s detail page. Resume when ready — the next run picks up exactly where it left off.

Manual Runs

Click Run Now to trigger an immediate sync outside the regular schedule. This is useful for testing configuration changes or backfilling after a pause.

Deleting a Loader

Deleting a loader stops all scheduled runs and removes the loader configuration. Existing data in your warehouse is not affected — tables and data remain until you manually clean them up.

Common Issues

IssueSolution
OAuth token expiredRe-authenticate by clicking “Reconnect” on the loader detail page
API rate limit exceededReduce sync frequency or select fewer objects
Target schema doesn’t existCreate the schema in your warehouse before saving the loader
”Permission denied” writing to warehouseEnsure the warehouse connection user has write access to the target schema
Initial sync taking too longLarge datasets may take hours for the initial backfill — subsequent incremental syncs will be much faster
Missing records after syncVerify the cursor field is correctly set and that the source API returns expected data for the date range

Next Steps

Last updated on