When to unify
Unification is useful when your customers use different systems for the same business object:- CRMs with contacts, companies, deals, and custom fields.
- ATS platforms with candidates, jobs, stages, and applications.
- Accounting systems with invoices, customers, transactions, and accounts.
- Support tools with tickets, comments, users, and organizations.
Design principles
Design the unified model around your product, not around the external APIs. If your app already has aContact, Invoice, or Candidate model, use that as the starting point. Keep the fields your workflows actually need, and resist carrying every provider field into the common model.
Expect optional fields. Providers rarely expose the same data with the same semantics, and some customers may rely on custom fields or custom statuses. Model those gaps intentionally with nullable fields, fallbacks, metadata, or provider-specific extensions.
Use the same model for reads and writes when possible. If a sync writes UnifiedContact records into your app, the corresponding create or update action should accept the same shape unless the write operation truly needs a different contract.
Validate close to the external API. Use data validation in your functions so mapping drift, malformed provider responses, and invalid write inputs fail at the integration boundary.
Define the model
Put shared schemas in a common file and import them from each provider implementation:models.ts
models.ts
Implement unified actions
Each provider gets an action with the same input and output contract:- Jira
- Zendesk
jira/actions/create-user.ts
Implement unified syncs
Sync functions are where read-side unification usually lives. Fetch provider records, map each page into your unified model, then save those records to Nango’s records cache:hubspot/syncs/users.ts
Handle provider-specific behavior
Use one of these patterns when the common model is not enough:- Extend the common model with provider-specific fields for integrations that need them.
- Store raw provider data under a
rawfield for debugging or advanced workflows. - Use connection metadata for customer-specific mappings, such as custom fields, custom statuses, or selected pipelines.
- Create provider-specific actions for operations that do not map cleanly to the unified interface.