Zuora
Sync customer, contact, and subscription data from your warehouse to Zuora. Keep your Zuora billing records enriched with the latest account information, contact details, and subscription metadata from your data warehouse.
Prerequisites
- A Zuora account (any plan that includes API access)
- An OAuth client with API write permissions
- Access to Zuora Settings (Administration section)
- Knowledge of which Zuora environment you want to target (Production, Sandbox, EU Production, or EU Sandbox)
Permissions
The OAuth client must have the following permissions:
- API Write Access: Required to create and update accounts, contacts, and subscriptions
- Billing Admin or Platform Admin role recommended for full access
Create a dedicated API user for Zeotap integrations rather than using a personal account.
Authentication
Zuora uses OAuth 2.0 client credentials for API authentication. Zeotap automatically handles token generation and refresh.
OAuth Client Credentials
- Log in to the Zuora UI
- Navigate to Settings > Administration > Manage Users
- Click on the API user you want to use (or create a new user with API access)
- Scroll to the OAuth Clients section and click Create
- Enter a name for the client (e.g.,
zeotap-sync) - Copy the Client ID and Client Secret displayed after creation
- Paste these values into the Client ID and Client Secret fields in Zeotap
Important: The client secret is only displayed once at creation time. If you lose it, you must create a new OAuth client.
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
| Environment | Select | Yes | The Zuora environment to connect to: US Production, US Sandbox, EU Production, or EU Sandbox. Use Sandbox for testing before switching to Production. |
Target Settings
| Field | Type | Required | Description |
|---|---|---|---|
| Zuora Object | Select | Yes | The Zuora object to sync data to: Accounts, Contacts, or Subscriptions. |
| ID Field | Text | No | The name of the mapped field that contains the Zuora object ID for update and upsert operations. Leave blank to always create new records. |
Supported Operations
Sync Modes
| Mode | Supported |
|---|---|
| Upsert | Yes |
| Insert | Yes |
| Update | Yes |
| Mirror | — |
Audience Sync Modes
| Mode | Supported |
|---|---|
| Add | — |
| Remove | — |
| Mirror | — |
| Upsert | — |
Zuora does not have a list or audience membership concept, so audience sync modes are not supported.
Features
- Field Mapping: Yes
- Schema Introspection: No — Zuora object fields are well-known and provided as default destination fields
Required Mapping Fields
| Object | Required Fields |
|---|---|
| Accounts | Account Name, Currency |
| Contacts | First Name, Last Name, Account ID |
| Subscriptions | (none — handled via Zuora subscription creation flow) |
Default Destination Fields
Account Fields
| Field | Type | Description |
|---|---|---|
Name | string | Name of the account |
Currency | string | Account currency (ISO 4217 code, e.g. USD) |
Status | string | Account status (Draft, Active, Canceled) |
Notes | string | Free-form notes on the account |
CrmId | string | CRM account ID for cross-system linking |
Batch | string | Billing batch for invoice generation |
PaymentTerm | string | Payment term (e.g. Net 30, Due Upon Receipt) |
Contact Fields
| Field | Type | Description |
|---|---|---|
FirstName | string | Contact first name |
LastName | string | Contact last name |
WorkEmail | string | Contact work email address |
WorkPhone | string | Contact work phone number |
Address1 | string | Street address line 1 |
Address2 | string | Street address line 2 |
City | string | City name |
State | string | State or province |
PostalCode | string | ZIP or postal code |
Country | string | Country name |
AccountId | string | Zuora account ID this contact belongs to |
Subscription Fields
| Field | Type | Description |
|---|---|---|
AccountId | string | Zuora account ID for the subscription |
TermType | string | Subscription term type (TERMED or EVERGREEN) |
ContractEffectiveDate | string | Date the subscription contract takes effect (YYYY-MM-DD) |
ServiceActivationDate | string | Date the service is activated (YYYY-MM-DD) |
Notes | string | Free-form notes on the subscription |
Any custom field prefixed with your tenant’s custom field namespace (typically ending in __c) is passed through directly to the Zuora API.
How It Works
-
Field Mapping: Zeotap maps your warehouse columns to Zuora object fields. Standard fields are sent as top-level properties in the API request. Custom fields (ending in
__c) are passed through directly. -
Batch API: Zuora’s Action API supports batch operations of up to 50 objects per request. Zeotap automatically chunks your data into batches of 50 for optimal throughput.
-
Request Format: Zeotap uses the Zuora v1 Action API (
/v1/action/createand/v1/action/update) with JSON request bodies. Each batch contains an array of objects and the Zuora object type. -
Sync Mode Behavior:
- Insert: Creates new objects for every row via
/v1/action/create. - Update: Updates existing objects via
/v1/action/update. Requires a Zuora object ID in the configured ID field. - Upsert: If a Zuora object ID is present, attempts to update the object. If the object is not found, falls back to creating a new one. Rows without an ID are created directly.
- Insert: Creates new objects for every row via
-
Per-Object Results: The Zuora Action API returns a success/failure status for each object in the batch. Zeotap tracks per-row results and reports individual errors.
-
Error Handling: Failed rows are tracked individually with per-row error details including Zuora error codes. Transient errors (rate limits, server errors) are retried automatically with exponential backoff.
Rate Limits
Zuora enforces concurrent request limits that vary by tenant and plan. The limits are not publicly documented as fixed numbers but are communicated via response headers:
Concurrency-Limit-Limit: Total number of permitted concurrent requestsConcurrency-Limit-Remaining: Remaining concurrent request slots
The OAuth token endpoint has a separate rate limit of 100 requests per minute per IP address.
Zeotap automatically handles rate limiting:
- HTTP 429 responses trigger exponential backoff with retry
- Up to 3 retries per request
- Token refresh is cached to avoid excessive token requests
Best Practices
- Use sandbox first: Configure your destination with the US Sandbox or EU Sandbox environment and validate the sync before switching to Production.
- Map the ID field: For upsert and update modes, always configure the ID Field in target settings and map a column containing the Zuora object ID. Without it, upsert mode creates duplicate records.
- Use CRM ID for linking: When syncing accounts, map the
CrmIdfield to link Zuora accounts back to your CRM for cross-system reconciliation. - Validate currency codes: The
Currencyfield on accounts must be a valid ISO 4217 currency code (e.g.,USD,EUR,GBP). Invalid codes cause the entire account creation to fail. - Batch size awareness: Zuora supports up to 50 objects per Action API call. Zeotap handles this automatically, but be aware that very large syncs will generate many API calls.
Troubleshooting
Authentication failed: invalid client_id or client_secret
Verify your OAuth client credentials are correct. The client secret is only shown once when the OAuth client is created. If you have lost the secret, create a new OAuth client in Zuora Settings > Administration > Manage Users.
Rate limited: too many token requests
Zuora limits the OAuth token endpoint to 100 requests per minute per IP. This usually indicates a misconfiguration causing excessive token generation. Zeotap caches tokens until they expire — if you see this error, check that multiple syncs are not simultaneously requesting new tokens.
Object ID is required for update mode
Update mode requires a Zuora object ID for each row. Ensure the ID Field is configured in target settings and that the corresponding column in your warehouse contains valid Zuora object IDs (32-character hex strings).
INVALID_VALUE error on create
This Zuora error typically means a required field is missing or has an invalid value. Check that all required fields for the object type are mapped and contain valid data. Common causes include missing Currency on accounts or invalid date formats on subscriptions (must be YYYY-MM-DD).
Currency mismatch on account update
Zuora does not allow changing the currency on an existing account. If your sync includes a Currency field and you are updating existing accounts, ensure the currency matches the account’s original currency or exclude the Currency field from your mapping for updates.
Contact creation fails with INVALID_ID
When creating contacts, the AccountId field must contain a valid Zuora account ID. Verify that the account exists in Zuora and that the ID is a valid 32-character identifier. Contacts cannot be created without a parent account.
Sandbox vs. production data mismatch
Sandbox and production are completely separate Zuora environments. Object IDs from sandbox do not exist in production. When switching environments, update your configuration and expect new objects to be created.
Sync is slow for large datasets
At 50 objects per API call, syncing 10,000 records requires 200 API calls. Zuora’s concurrent request limits may further throttle throughput. Schedule large syncs during off-peak hours and consider breaking very large syncs into multiple smaller batches.