Sage Intacct
Sync data from your warehouse to Sage Intacct. Keep your ERP records enriched with the latest customer, vendor, and financial data from your data warehouse, enabling accurate financial reporting and streamlined accounts management.
Prerequisites
- A Sage Intacct account with Web Services enabled
- A Sage Intacct Developer App with OAuth 2.0 credentials (Client ID and Client Secret) from the Sage Developer Portal
- An access token obtained via the OAuth 2.0 authorization flow
- Appropriate permissions to create or update the target objects in Sage Intacct
- For multi-entity companies, the entity ID for the target entity
Permissions
The Web Services user or OAuth 2.0 application must have the following permissions in Sage Intacct:
- Read access to the target object type (for connection testing)
- Create access (for insert and upsert sync modes)
- Update access (for update and upsert sync modes)
- For multi-entity setups, the user must be assigned to the target entity via Company > Admin > Users > User entities
Authentication
Sage Intacct uses OAuth 2.0 for authentication via the REST API.
OAuth 2.0 Client Credentials
- Log in to the Sage Developer Portal
- Navigate to your Developer App settings
- Copy the Client ID and Client Secret
- Complete the OAuth 2.0 authorization flow to obtain an Access Token and Refresh Token
- Paste the credentials into the corresponding fields in Zeotap
Important: Access tokens expire after 12 hours. If you provide a refresh token, Zeotap automatically refreshes expired tokens. Refresh tokens are valid for 6 months. Without a refresh token, you must manually update the access token when it expires.
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
| Company ID | Text | Yes | Your Sage Intacct company ID. Found in Company > Admin > Company in the Sage Intacct UI. |
| Entity ID | Text | No | Entity ID for multi-entity companies. Required for entity-level objects such as timesheets, projects, and invoices. Leave blank for top-level access. |
Target Settings
| Field | Type | Required | Description |
|---|---|---|---|
| Object Type | Select | Yes | The Sage Intacct object to sync data to. Options: Customer, Vendor, Invoice, Bill, Journal Entry, Employee, Contact, Project, GL Account. |
Supported Operations
Sync Modes
| Mode | Supported |
|---|---|
| Upsert | Yes |
| Insert | Yes |
| Update | Yes |
| Mirror | — |
Audience Sync Modes
| Mode | Supported |
|---|---|
| Add | — |
| Remove | — |
| Mirror | — |
| Upsert | — |
Sage Intacct does not have a list or audience membership concept, so audience sync modes are not supported.
Features
- Field Mapping: Yes
- Schema Introspection: No — Sage Intacct object schemas vary by company configuration and customization; fields are provided as defaults
Required Mapping Fields
| Object | Required Fields |
|---|---|
| All objects | id (Record ID) |
The id field is used to match existing records for update and upsert operations. For insert mode, the id field is optional and Sage Intacct assigns a system-generated key.
Default Destination Fields
| Field | Type | Description |
|---|---|---|
id | string | Sage Intacct record key (read-only on insert, used for update/upsert) |
name | string | Display name of the record |
status | string | Record status (e.g., active, inactive) |
displayContact.companyName | string | Company name for customer or vendor records |
displayContact.firstName | string | Contact first name |
displayContact.lastName | string | Contact last name |
displayContact.email1 | string | Primary email address |
displayContact.phone1 | string | Primary phone number |
displayContact.mailingAddress.addressLine1 | string | Street address line 1 |
displayContact.mailingAddress.city | string | City name |
displayContact.mailingAddress.state | string | State or province |
displayContact.mailingAddress.zip | string | Postal or ZIP code |
displayContact.mailingAddress.country | string | Country code or name |
Sage Intacct supports nested field names using dot notation. Fields not in the default list can be mapped manually using the field names from your Sage Intacct instance.
How It Works
-
Field Mapping: Zeotap maps your warehouse columns to Sage Intacct object fields. Nested fields use dot notation (e.g.,
displayContact.email1) and are sent as nested JSON objects in the request body. -
Request Format: The Sage Intacct REST API uses JSON request bodies. Zeotap sends
application/jsoncontent type with Bearer token authentication on every request. -
Per-Record API Calls: Each row in your sync results in a single API call to Sage Intacct. Zeotap processes rows sequentially within each batch for reliable per-row error tracking.
-
Sync Mode Behavior:
- Insert: Creates a new record via
POST /ia/api/v1/objects/{objectType}. - Update: Updates an existing record via
PUT /ia/api/v1/objects/{objectType}/{id}. Requires a record ID in the mappedidfield. - Upsert: If a record ID is present, updates the record via
PUT. If no ID is present, creates a new record viaPOST.
- Insert: Creates a new record via
-
Entity Scoping: For multi-entity companies, entity scoping is applied when the OAuth access token is issued or refreshed — Zeotap passes the configured entity ID to the Sage Intacct token endpoint, and the resulting token is scoped to that entity for every subsequent API request. Make sure the access token you initially provide was also issued for the same entity (or the top-level company if no entity is configured).
-
Token Management: When a refresh token is provided, Zeotap automatically refreshes expired access tokens. Access tokens expire after 12 hours; refresh tokens are valid for 6 months.
-
Error Handling: Failed rows are tracked individually with per-row error details. Transient errors (rate limits, server errors) are retried automatically with exponential backoff up to 3 retries.
Rate Limits
Sage Intacct limits the number of concurrent connections to the gateway by tenant (company ID). A typical tenant defaults to 2 concurrent connections, though this varies by service level agreement.
Zeotap automatically handles rate limiting:
- HTTP 429 responses trigger exponential backoff with retry
- The
Retry-Afterheader is respected when present - Up to 3 retries per request
Because Sage Intacct has low default concurrency limits, syncing large datasets may take longer than with other destinations. Consider scheduling syncs during off-peak hours to minimize contention with other integrations.
Best Practices
- Use a dedicated Web Services user: Create a dedicated user for API integrations to avoid conflicting with interactive user sessions and to simplify permission management.
- Configure entity ID for multi-entity: If your Sage Intacct instance uses multiple entities, always set the Entity ID field. Using one user for multiple entities without specifying the entity can cause token conflicts.
- Map the record ID for upsert/update: Always map a column containing the Sage Intacct record key to the
idfield for upsert and update sync modes. Without it, upsert mode creates duplicate records. - Use nested field notation: Sage Intacct objects use nested structures. Map fields using dot notation (e.g.,
displayContact.email1) to ensure data reaches the correct nested property. - Monitor token expiry: If not using a refresh token, monitor access token expiry (12 hours) and update credentials before they expire. Using a refresh token is strongly recommended for unattended syncs.
- Start with a small test sync: Validate your field mappings with a small batch before running a full sync, especially for complex objects like invoices or journal entries that have strict validation rules.
Troubleshooting
Authentication failed: invalid or expired access token
Verify your access token is valid and has not expired. Access tokens expire after 12 hours. If you provided a refresh token, check that it has not been revoked or expired (valid for 6 months). Regenerate credentials from the Sage Developer Portal if needed.
Record ID is required for update mode
Update mode requires a Sage Intacct record key for each row. Ensure the id field is mapped in your field mapping and that the corresponding column in your warehouse contains valid Sage Intacct record keys.
Entity access denied (403)
The Web Services user does not have access to the specified entity. Assign the user to the target entity via Company > Admin > Users > User entities in Sage Intacct. For multi-entity companies, verify the Entity ID field is set correctly in the destination configuration.
Rate limiting (429 errors)
Sage Intacct limits concurrent connections per company (typically 2). Zeotap retries automatically, but persistent rate limit errors may indicate too many integrations sharing the same company. Reduce sync frequency, stagger sync schedules, or contact Sage to request a higher concurrency limit.
Invalid object type or field name
Verify the object type and field names match your Sage Intacct configuration. Custom fields and objects may have different API names than their display names. Check the Sage Intacct REST API object model documentation for the correct field paths.
Invoice or bill creation fails with validation errors
Complex financial objects like invoices and bills have strict validation rules (e.g., required line items, valid GL account references, matching currency codes). Review the error message for specific field validation failures. Ensure all required nested objects and reference fields are mapped correctly.
Connection timeout
Sage Intacct API requests have a 120-second timeout. If timeouts occur consistently, check that your Sage Intacct instance is accessible and not under heavy load. Network issues between Zeotap and the Sage Intacct API gateway can also cause timeouts.
Duplicate records created in upsert mode
Ensure you are mapping a column with valid Sage Intacct record keys to the id field. If the id field is empty or missing for a row, upsert mode falls back to creating a new record. Verify your warehouse data contains the correct record identifiers.