Skip to content

Merge.dev vs Truto: The 2026 Migration & Performance Playbook

A technical playbook for evaluating Merge.dev alternatives and executing a zero-downtime migration - OAuth tokens, schema mapping, and rollback plans.

Nachi Raman Nachi Raman · · 33 min read
Merge.dev vs Truto: The 2026 Migration & Performance Playbook

If you are evaluating Merge.dev for your unified API strategy, the initial pitch sounds highly appealing: one API, hundreds of integrations, ship your product faster. But the architectural realities of scaling a B2B SaaS product tell a different story. Eventually, you do the math on managing thousands of linked accounts at $65 each. Your biggest enterprise customer demands support for a heavily customized Salesforce object. Your security team flags that Merge is storing a cached copy of every customer's HR data on their servers.

You are not the first engineering team to hit this wall. If you are evaluating how to move off Merge.dev without forcing your enterprise customers to re-authenticate, this playbook gives you the exact architectural pattern: extract OAuth tokens, mirror your existing response shapes through declarative mappings, and swap the underlying engine behind your existing endpoints. The migration itself is a structured engineering exercise—not a six-month re-platform.

This guide is a direct, highly technical Merge.dev migration playbook written for senior product managers and engineering leaders. We will break down exactly where Merge.dev falls short at scale, why Truto's programmable, zero-data-retention API is the superior alternative for enterprise SaaS integrations, and how to execute a zero-downtime migration without forcing your enterprise customers to click "Reconnect."

Why Migrate: When to Consider Leaving Merge.dev

Migration is an infrastructure decision, not an emotional one. There are five concrete triggers that make leaving Merge.dev a rational business choice - if any two apply, the total cost of staying already exceeds the migration effort.

Most teams don't leave a unified API vendor because of a single catastrophic incident. They leave because the architectural assumptions that made sense at 20 customers stop making sense at 200. Here are the signals that migration has moved from "someday" to "this quarter":

  1. Your linked-account count crossed 150-200. The per-account pricing curve is steepest between 100 and 500 accounts, and this is where teams first realize their middleware line item is growing faster than their revenue.
  2. An enterprise deal requires custom object or custom field support that isn't covered. If your sales team is losing deals because the vendor's Common Data Model doesn't include a specific Salesforce or Workday field, you have a product-market fit problem masquerading as an integration problem.
  3. Your security team blocked a deal over data residency or third-party processor concerns. A cached copy of customer CRM or HRIS data sitting in a vendor's US-region database is a hard blocker for EU financial services, healthcare, and regulated industry buyers.
  4. Your AI agent product needs tool granularity the platform doesn't expose. If your agent needs composite actions, tenant-scoped tool definitions, or provider-specific endpoints that the pre-built catalog doesn't cover, you will fight the platform on every new capability.
  5. Sync latency is causing user-visible bugs. If your users see stale HubSpot data because the polling window is 15 minutes, and your product's value prop depends on real-time state, no amount of prompt engineering fixes an architectural cache miss.

If none of the above apply, stay. Migration has real cost. If two or more apply, the compounding cost of staying is already higher than the one-time cost of leaving.

The Hidden Costs of Merge.dev at Scale

The unit economics of B2B SaaS rely on predictable infrastructure costs. Merge's pricing model actively penalizes growth by tying your middleware costs directly to your customers' adoption.

Early-stage decisions optimize for speed. You use a platform that owns the OAuth application, forces you into their predefined data models, and handles the sync logic. As your customer base grows, the operational reality changes drastically.

The 2026 SaaS statistics report from BetterCloud tracks the average number of SaaS apps per company at 106, a trend we analyzed in our 2026 unified API benchmark. Your customers expect your product to connect to their CRM, their HRIS, their ticketing system, and their accounting software. B2B vendors moving upmarket are expected to plug into a meaningful slice of that stack.

Merge's public pricing is unambiguous. Merge charges $650/month for up to 10 total production Linked Accounts, then $65 per Linked Account after that. A Linked Account is one customer connection to one third-party system. If a single customer connects three integrations (e.g., Salesforce, Jira, and BambooHR), you pay three times.

Let's run the math on a modestly successful mid-market SaaS company. If 100 customers each connect 2 integrations, you are looking at $13,000 per month—$156,000 annually—just in linked account fees. At 1,000 connections, the bill climbs to roughly $65,000/month, before any premium features or overage uplift. If your core SaaS product charges $500 per month, you are spending a massive percentage of your gross margin just to move data back and forth.

There are secondary cost traps worth pricing into your TCO model:

  • Annual capacity commits: Almost all Merge plans require an annual contract with capacity-based pricing, meaning you commit to a minimum number of linked accounts at the beginning of your contract, regardless of actual usage.
  • Forecasting drag: Most teams overestimate their linked account needs in the first 12 months by 2-3x, which compounds the overcommit problem.
  • Enterprise-gated features: Need to know when data was deleted in an external API? According to Merge, that makes you an Enterprise customer requiring a custom contract.

Stop being punished for growth by per-connection API pricing. The fix is not to negotiate harder on $65. It is to decouple your integration cost curve from your customer growth curve. Unified APIs should be priced based on compute and actual usage. Truto bills per integration category, entirely eliminating the per-linked-account tax that ruins your unit economics.

Sync-and-Store vs Zero Data Retention

A sync-and-store architecture creates massive compliance liabilities. A zero data retention API acts as a pure pass-through proxy, keeping your data out of third-party databases.

Merge.dev's core architecture relies on background data synchronization. When a third-party system updates, Merge pulls that data, normalizes it, and stores a copy in their own database. When your application queries Merge, you are actually querying Merge's cached version of the data, not the live third-party system. Data is encrypted and SOC 2 compliant, but remains stored until explicitly deleted.

This creates massive engineering and compliance headaches:

  1. Data Strikethrough and Latency: You are at the mercy of Merge's polling intervals. If a sales rep updates a deal in HubSpot, your application won't see that update until Merge decides to run its next sync job.
  2. Compliance Friction and DPAs: Storing a redundant copy of your customers' highly sensitive CRM, HRIS, and payroll data in a middleware vendor's database creates a massive attack surface. For AI agents that process HR data, financial records, or inbound emails, a cached copy of your customer's data sitting in a third-party system is a security review red flag. Passing enterprise security reviews becomes significantly harder.
  3. Webhooks are Delayed: Because events rely on polling diffs rather than real-time provider webhooks, event-driven architectures suffer from artificial latency.

Truto takes a radically different approach. Truto is a pure pass-through proxy layer. We do not store your payload data.

graph TD
    subgraph Merge Sync-and-Store
        A1[Third-Party API] -->|Polling| B1[(Merge Database)]
        B1 -->|Cached Read| C1[Your Application]
    end

    subgraph Truto Zero Data Retention
        A2[Third-Party API] <-->|Real-Time Proxy| B2{Truto Engine}
        B2 <-->|Normalized JSON| C2[Your Application]
        B2 -.->|No payload persisted| D2[(Token Store Only)]
    end

When you make a request to Truto, our generic execution engine dynamically translates your unified request into the provider-specific format, fetches the live data directly from the third-party API using the connected account's credentials, normalizes the response in memory using JSONata, and returns it to you immediately.

This zero data retention API architecture ensures you are always reading the live state of the third-party system. Your DPA gets shorter because there is no third-party processor holding customer records, regional data residency becomes a simple routing concern, and the blast radius of a vendor breach is limited to OAuth credentials, not the underlying customer payloads.

Trade-off worth naming: A pure pass-through model means you cannot ask Truto for "all contacts updated in the last 90 days" as a single warehouse query, because Truto did not retain them. If you need that pattern, you either run a sync into your own data store or keep a separate ETL pipeline.

Handling Custom Objects and Schema Rigidity

Unified APIs fail when they force enterprise data into rigid schemas. Truto solves this using a 3-level JSONata override hierarchy that requires zero code deployments.

The promise of a unified API is that you write code once against a single schema, and it works for 50 different CRMs. The reality is that no two enterprise Salesforce instances are exactly alike.

Merge forces you into their predefined Common Data Models. If your biggest Salesforce customer has a custom object called Opportunity_Phase__c with five fields you have never seen before, a rigid unified schema fails. You are forced to either (a) drop the data into a generic custom_fields blob, (b) upgrade to a contract-based enterprise plan to get custom field mapping, or (c) bypass the unified model entirely and write raw passthrough requests—defeating the entire purpose of using a unified API in the first place.

Truto's architecture contains zero integration-specific code. The entire platform handles integrations purely as declarative configuration.

Integration-specific behavior is defined entirely as JSONata expressions. JSONata is a functional, Turing-complete query and transformation language for JSON. Because these mappings are just strings stored in a database, Truto offers a 3-level override hierarchy that lets you modify mappings without touching source code.

Info

The 3-Level Override Hierarchy

  • Level 1 (Platform): The default mapping that ships with the connector and works for most standard use cases.
  • Level 2 (Environment): Your specific environment can override the base mapping. If you want to permanently map a specific custom field across all your customers, you do it here.
  • Level 3 (Account): Individual connected accounts can have their own overrides. If exactly one enterprise customer has a strange Salesforce configuration, you apply a JSONata override exclusively to their integrated_account record.

Here is a simplified example of how you can override a response mapping for a specific enterprise account to pull in a custom Salesforce field, without deploying a single line of backend code. Deep-merging happens at runtime:

# Account-level override merged on top of the platform default
response_mapping: >-
  $merge([
    $$.response_mapping,
    {
      "custom_fields": {
        "opportunity_phase": response.Opportunity_Phase__c,
        "contract_value": response.Contract_Value__c,
        "enterprise_score": response.Custom_Lead_Score__c
      }
    }
  ])

This architecture eliminates the SaaS integration maintenance cost associated with schema drift. You handle edge cases with configuration data, not by branching your codebase. The pay-off is that adding support for a custom object becomes a config change instead of a sprint, and your enterprise customers stop being blocked by your vendor's product roadmap.

Operational Risks of Pre-Built Connector Packs

Pre-built connector catalogs trade initial speed for long-term operational risk. When every connector is a black box maintained by a vendor's engineering team, your integration roadmap is no longer yours.

Merge ships two distinct products: a unified API across categories like HRIS, ATS, CRM, and accounting, and Merge Agent Handler (launched October 2025), which exposes pre-built tools to AI agents over MCP. Agent Handler introduces a concept called Tool Packs - configurable bundles of connectors and their specific tools that your agent can access. The appeal is obvious: connect your agent to Salesforce, Jira, and Slack in an afternoon.

The operational risks become apparent once you move past prototyping.

You cannot modify a tool that doesn't fit. Merge's pre-built tools are maintained by Merge. If a tool doesn't cover the operation your agent needs at the right granularity, you can't modify it. You cannot author custom tool calls and deploy them to the platform. If your agent needs a composite action - say, creating a Greenhouse candidate and simultaneously attaching a parsed resume - and that exact operation doesn't exist in the Tool Pack, you're stuck filing a feature request.

Tool definitions are identical across all tenants. Every customer gets the same tool behavior. There is no per-org scope configuration, no tenant-specific field mappings, no custom validation per customer. For multi-tenant B2B products where Enterprise Customer A has a completely different Salesforce schema than Enterprise Customer B, this is a hard wall.

Custom objects are narrowly supported. Merge currently supports custom objects for Salesforce, HubSpot, and Zendesk Sell only. Custom fields are gated to the Professional plan. If your customer runs a CRM that isn't one of those three - or an HRIS with custom entities - the unified schema simply won't see that data.

Closed-source runtime means zero visibility. You cannot inspect connector code, modify behavior, or add new APIs. When a connector breaks because a provider changed their API, you wait for Merge's engineering team to ship the fix. You have no visibility into their connector update cadence, no published SLAs for how quickly they patch breaking changes, and no ability to hotfix a connector yourself.

The Agent Handler does not include data syncs or webhook processing. It's a separate product from the unified API, sold and priced separately. Teams that need both agent tool calls and background data synchronization are running two products from the same vendor with different capabilities and constraints.

The fundamental issue is dependency. Your customers' integration experience - uptime, data freshness, field coverage - is bounded by your vendor's engineering bandwidth and prioritization. When a provider ships a breaking API change on a Friday, your options are limited to waiting or building a workaround that bypasses the platform you're paying for.

Truto takes a different approach. Because integration behavior is defined as declarative JSONata configuration rather than compiled connector code, you can modify mappings, add fields, and adjust behavior at the environment or account level without waiting on anyone's roadmap. Truto's MCP server exposes your integration's native resources directly through the proxy API, so the tools your agents call correspond to the integration's actual API format - including custom objects and custom fields - not a pre-built subset.

The Merge.dev Alternatives Landscape

Not every Merge.dev alternative solves the same problem. The market breaks into three architectural camps, and picking the wrong camp is more expensive than picking the wrong vendor within a camp.

Before you start a migration, understand what you are actually replacing. Merge.dev sits in the "unified API" camp, but the broader embedded integration space includes iPaaS platforms, workflow automation tools, and developer-first proxy layers - each with different assumptions about who writes the integration logic and where the data lives.

Camp 1: Unified APIs (developer-first, single API surface)

These platforms give you one normalized API per category (CRM, HRIS, ATS, accounting) and hide provider differences behind a common schema. The trade-off is schema rigidity in exchange for a small integration surface.

  • Merge.dev - The category incumbent. Sync-and-store, per-linked-account pricing, closed connector runtime, Common Data Model with narrow custom-object support.
  • Apideck - Unified API across CRM, HRIS, accounting, and file storage. Similar architectural pattern to Merge with its own normalized schemas.
  • Finch - Vertical-focused unified API for employment and payroll data. Not a Merge replacement outside HRIS/payroll use cases.
  • Truto - Zero data retention, declarative JSONata mappings, pass-through proxy, integration-category pricing (not per-linked-account).

Pick a unified API if your integration surface is bounded to well-known categories, and your customers mostly run standard configurations. Skip unified APIs if every enterprise deal requires custom schema work.

Camp 2: Embedded iPaaS (visual workflow builders, in-app integration UX)

These platforms let you (or your customers) build visual workflows that run inside your product. They are optimized for automation logic, not for consistent data models across providers.

  • Workato Embedded - Enterprise iPaaS with an embedded offering. Deep connector library, visual recipe builder, priced for enterprise-tier deals.
  • Tray.io (Tray Embedded) - Low-code workflow builder aimed at product teams that want to expose integration UX to customers. Merger-formed entity now positioning around composable AI + integration.
  • Paragon - Embedded iPaaS pitched specifically at SaaS product teams. Visual workflow builder, hosted auth, per-integration-object pricing model.

Pick an embedded iPaaS if your product's value prop includes letting your customers build their own automations across many tools. Skip embedded iPaaS if you want a single API surface your backend calls; the visual workflow layer becomes overhead when you already have code.

Camp 3: Developer workflow automation (trigger-action platforms)

Originally built for citizen developers, these platforms increasingly ship developer-focused offerings for embedding automation into products.

  • Zapier for Developers / Zapier Embed - Massive connector catalog, hosted trigger-action model. Not designed for high-throughput backend calls; better for user-facing automation.
  • Pipedream - Developer-first code-and-workflow platform. Lets you write Node/Python inline in workflows. Strong for prototyping event pipelines, less for productizing multi-tenant integration UX.
  • n8n (self-hosted) - Open-source workflow automation. Not a hosted unified API, but teams sometimes evaluate it as an escape hatch when they want full control of connector code.

Pick workflow automation if you need breadth over depth (thousands of apps, shallow use cases) or you are building user-facing automation UX. Skip it if you need consistent multi-tenant data models, backend-driven sync, or strict data residency.

Which alternatives simplify migration off Merge?

The answer depends on architectural similarity to what you already have:

  • Pass-through proxy alternatives (Truto) make migration easier because the mental model is closer to "replace the base URL and remap the response shape." No warehouse to rebuild, no sync jobs to reconfigure, no polling intervals to tune.
  • Sync-and-store alternatives (Apideck-style architectures) require you to reprovision the data warehouse, wait for the initial backfill to complete, and reconcile the two caches during cutover. Migration windows are longer.
  • iPaaS alternatives (Paragon, Workato Embedded, Tray) require you to rebuild your integration surface as visual workflows. This is a full architectural shift, not a migration - budget quarters, not weeks.
  • Workflow automation alternatives (Pipedream, Zapier) rarely serve as one-for-one Merge replacements because the trigger-action model doesn't match a synchronous read-through API surface.

The rest of this playbook assumes you are migrating to a pass-through unified API. The steps translate for other targets, but the timelines and risks are different.

Performance and API Rate Limit 429 Handling

Opaque rate limiting destroys background sync reliability. Developers need direct visibility into HTTP 429 errors and standardized IETF headers to manage their own backoff queues.

Merge.dev enforces strict API rate limits on its unified API, capping Launch plan users at 100 requests per minute per linked account. That is on top of whatever the underlying provider (Salesforce, HubSpot, Workday) is already enforcing. Two stacked rate limiters mean two places your AI agent or sync job can stall, with two different error formats.

Worse, many unified APIs attempt to "help" by silently swallowing HTTP 429 (Too Many Requests) errors and applying their own opaque exponential backoff. This breaks your internal queueing systems. A retry storm happens when a request fails, your code immediately retries, also fails, retries again, and suddenly three users are each retrying five times—15 requests where there were 3. Your retry logic creates more traffic, causing more 429s, causing more retries. It is a death spiral.

Truto believes in radical transparency. We do not retry, throttle, or absorb HTTP 429 responses from upstream APIs on your behalf. The upstream API's rate limit is the source of truth. When HubSpot or Salesforce returns a 429, Truto passes that error directly to the caller.

However, dealing with 50 different rate limit header formats is painful. Truto normalizes upstream rate limit information into standardized headers per the IETF RateLimit Header Fields specification:

  • ratelimit-limit: The maximum number of requests allowed in the current window.
  • ratelimit-remaining: The number of requests remaining in the current window.
  • ratelimit-reset: The time at which the rate limit window resets.

By passing these standardized headers back to your application, your engineering team retains complete control over your circuit breakers, retry queues, and backoff logic. You get the normalization of a unified API without losing the low-level architectural control required for high-throughput enterprise systems.

A minimal handler that uses the normalized headers looks like this:

async function callUnified(url: string, opts: RequestInit, attempt = 0): Promise<Response> {
  const res = await fetch(url, opts);
  if (res.status !== 429) return res;
 
  const reset = Number(res.headers.get('ratelimit-reset') ?? '1');
  const remaining = Number(res.headers.get('ratelimit-remaining') ?? '0');
  const jitter = Math.random() * 250;
  const waitMs = Math.min(reset * 1000, 30_000) + jitter;
 
  if (attempt >= 5) throw new Error(`429 after 5 attempts, remaining=${remaining}`);
  await new Promise(r => setTimeout(r, waitMs));
  return callUnified(url, opts, attempt + 1);
}

You own the backoff curve, the max attempt count, and the jitter. If you are running an AI agent that needs to fall back to a cached response on 429, that decision belongs in your code, not a vendor's black box.

Pre-Migration Checklist: Security, Tokens, Data Residency

The migration itself is the easy part. The hardest work happens before you write a single line of new code - auditing what you own, what you don't, and what your compliance team will ask about.

Before you touch a token export endpoint, walk through this checklist. Skipping any of these items is how migrations turn into six-month projects with a reconnect campaign at the end.

Security and access audit

  • Inventory every OAuth application in use. For each provider, document the client_id, the scopes granted, the redirect URIs, and who owns the developer portal account.
  • Identify which OAuth apps you own vs which the vendor owns. This is the single biggest determinant of migration difficulty. Vendor-owned apps mean the refresh tokens are non-transferable.
  • Rotate any shared credentials before starting. If your integration secrets are in a shared vault, tighten access to the migration lead and a backup engineer only.
  • Audit vendor API keys and webhook signing secrets. Note expiry dates. You don't want a webhook secret rotating mid-cutover.
  • Get sign-off from your security team on the migration plan. They will ask about token custody during transit, encryption at rest during export, and deletion SLAs at the old vendor.

Token and credential inventory

  • Export a full list of linked accounts. Provider, customer ID, connection date, last sync status, granted scopes.
  • Classify accounts by transferability. Bucket A: refresh tokens issued to your OAuth app (transferable). Bucket B: tokens issued to vendor's OAuth app (require re-auth). Bucket C: expired or broken (drop from migration scope).
  • Confirm token export mechanics with your current vendor in writing. Some vendors gate raw token access behind enterprise contracts. Get this in an email before you plan the timeline.
  • Prepare an encrypted staging store for exported tokens. Envelope-encrypted, access-logged, with a 30-day retention policy that deletes the export after cutover completes.

Data residency and compliance

  • Document current data residency. Where does your existing vendor store cached data? Which region processes webhooks? Which region hosts the token store?
  • Match the new vendor's residency options to your customer commitments. EU customers with GDPR clauses, US public sector with FedRAMP considerations, healthcare with HIPAA - each has different regional requirements.
  • Update your subprocessor list. Removing the old vendor and adding the new one is a customer-facing DPA change. Notify enterprise customers per the notice period in your contracts (typically 30 days).
  • Confirm deletion SLA at the outgoing vendor. When you cancel, how long until customer data is purged? Get the deletion certificate in writing.
  • Re-run your security review checklist for the new vendor. SOC 2 Type II, ISO 27001, penetration test summary, incident response plan, data processing addendum.

Application readiness

  • Feature-flag the base URL. Every call to your unified API should route through a config that can be swapped per integration, per environment.
  • Add correlation IDs to every outbound integration call. You will need these to diff old-vs-new responses during the dual-read phase.
  • Instrument response latency, error rates, and field-level nulls per integration. You need a baseline before you can prove the new vendor is at least as reliable.
  • Identify write paths vs read paths. Writes are more dangerous during cutover. Plan a read-first cutover, then writes after 7 days of stability.

The Zero-Downtime Merge.dev Migration Playbook

Migrating off a legacy unified API requires extracting your OAuth tokens, remapping your data models, and swapping the underlying infrastructure without your customers noticing.

If you are ready to escape the per-account pricing trap, you need a highly structured strategy. The single failure mode that kills these migrations is forcing customers to re-authorize. Every reconnect is a support ticket, a Slack message to an internal champion who has since left the company, and a measurable bump in integration churn.

Here is the exact architectural playbook to migrate from Merge.dev without re-authenticating customers.

Step 1: Audit OAuth App Ownership Per Provider

For each provider (Salesforce, HubSpot, Greenhouse, etc.), confirm whether the OAuth client_id belongs to you or to Merge. If you are using Merge's white-labeled OAuth apps, you will need to create your own OAuth applications in the developer portals of the respective providers. If Merge owns the app, you cannot transfer the refresh tokens—they were issued to a different OAuth client. In that case, you either negotiate a transfer with Merge (rare) or accept a controlled reconnect campaign for that specific provider only.

Step 2: Export Tokens and Account Metadata from Merge

Use Merge's account token endpoints (or request a secure export from support) to pull the access_token, refresh_token, expires_at, and any provider-specific context (Salesforce instance_url, Zendesk subdomain, HubSpot portal ID). Store the export encrypted at rest—these are bearer credentials to your customers' systems.

Format the payload into Truto's integrated_account schema:

{
  "integration_name": "salesforce",
  "environment_id": "env_12345",
  "context": {
    "oauth": {
      "access_token": "extracted_access_token",
      "refresh_token": "extracted_refresh_token",
      "expires_at": "2026-10-15T10:30:00Z",
      "instance_url": "https://your-instance.my.salesforce.com"
    }
  }
}

Step 3: Register Accounts on Truto (The App Swap)

Truto's integrated account model accepts pre-existing credentials. You POST the token bundle along with a customer identifier, and the platform stores it in a generic credentials context. You plug your new Client ID and Client Secret into Truto's integration configuration. Truto will use these credentials to refresh the tokens you imported. As long as the underlying permissions haven't changed, Truto successfully generates new access tokens using your new OAuth app credentials, and the account stays live.

Step 4: Mirror Your Old API Shape via JSONata

Your frontend and backend systems are currently expecting data shaped exactly like Merge's Common Data Model. If you simply swap the API endpoint, your code will break.

Instead of rewriting your entire application, use Truto's Level 2 (Environment) JSONata overrides to force Truto to output data that exactly mimics the legacy Merge schema. This translation layer acts as an anti-corruption layer. Your application code remains completely untouched.

A fragment that mirrors a Merge-style contact:

response_mapping: >-
  {
    "remote_id": response.id,
    "first_name": response.first_name,
    "last_name": response.last_name,
    "email_addresses": [{ "value": response.email, "email_address_type": "work" }],
    "phone_numbers": response.phones.{ "value": number, "phone_number_type": type },
    "remote_data": [{ "path": "/contact", "data": response }]
  }

Step 5: Webhook Normalization

Truto acts as a unified webhook receiver. Update the webhook URLs in your third-party provider dashboards to point to Truto's /integrated-account-webhook/:integratedAccountId endpoint. Truto verifies the webhook signatures, transforms the raw payload into a standardized event format using JSONata, enriches the data by fetching the full resource, and delivers it to your internal queue.

Step 6: Dual-Write and Diff for 7-14 Days

Route a copy of every read through both platforms. Hash and compare responses. Log any divergence to a structured table. Most diffs will be (a) timestamp formatting, (b) custom field handling, and (c) the order of array elements. Fix these in the JSONata mapping, not in your application code.

Tip

If you are migrating a write-heavy integration (e.g., creating Greenhouse candidates), do dual-writes only in a sandbox environment first. Diffing read responses is safe. Diffing writes by actually creating duplicate records is not.

Step 7: Cut Over Reads and Deprecate

Once the webhooks are re-routed and the JSONata translation layer is tested, you simply swap the base URL in your API client from api.merge.dev to api.truto.one via a feature flag, integration by integration. Keep the old contract live for a week as a fallback. Once error rates and diff counts are clean, stop paying for the old platform.

The migration is complete. Your customers experience zero downtime, they do not have to re-authenticate, and your infrastructure costs instantly decouple from your customer growth.

Token and Credential Migration Strategies

Not every token can move. Your migration plan needs three distinct strategies - one for each ownership scenario - because a one-size-fits-all approach either breaks accounts or triggers unnecessary reconnect campaigns.

Token portability is the single biggest variable in migration effort. Before you start, sort every provider into one of three buckets and apply the matching strategy.

Strategy A: You own the OAuth app (direct token import)

If your client_id is registered in the provider's developer portal under your account, refresh tokens are portable across any middleware. The new platform can call the provider's token refresh endpoint with your credentials and mint fresh access tokens without customer involvement.

Migration steps:

  1. Export access_token, refresh_token, expires_at, and any provider-specific context (instance URLs, tenant IDs, portal IDs).
  2. Encrypt in transit and at rest during handoff to the new platform.
  3. POST into the new platform's integrated account API with the customer identifier preserved.
  4. Trigger a test refresh on each account to confirm the token still resolves.
  5. Monitor for provider-side revocations in the first 48 hours (some providers alert customers about token activity).

Customer friction: Zero. No email, no reconnect, no support ticket.

Strategy B: The vendor owns the OAuth app (progressive re-auth)

If the outgoing vendor's client_id is what your customers granted consent to, those refresh tokens will not work with your new platform - they were issued to a different OAuth client. You cannot brute-force this. The customer has to grant consent to your new OAuth app.

The naive approach is to email every customer asking them to reconnect. Don't do that. It creates a support wave and signals instability. Use progressive re-auth instead (detailed in the next section).

Strategy C: API-key based integrations (silent rotation)

Providers that use API keys or personal access tokens (e.g., some ticketing tools, custom REST APIs, certain HRIS providers) don't have OAuth flows to worry about. The key itself is the credential.

Migration steps:

  1. Export the API key value from the old platform's account store.
  2. Import into the new platform's credential context (usually a context.api_key field).
  3. Rotate the key with the customer's consent if the key is old or scoped too broadly.
  4. Test one live call per account before cutover.

Customer friction: Zero for silent rotation, low for scoped-rotation cases where the customer needs to generate a new key.

Handling mixed portfolios

Most teams have all three scenarios in their portfolio. Sequence the migration so you tackle Strategy A providers first (fastest wins, zero friction), then Strategy C (silent rotation), then Strategy B providers last with a planned progressive re-auth campaign. This front-loads success and shrinks the reconnect campaign to only the accounts that truly need it.

The Zero-Downtime Re-Auth Pattern

When you cannot transfer tokens, you can still avoid a synchronous reconnect campaign. The pattern is called shadow-consent: silently prompt for consent on next active use, not by email blast.

Progressive re-auth is what separates a professional migration from a chaotic one. When Strategy B applies (vendor owns the OAuth app), you have three options ranked by customer friction:

Intercept the next authenticated user action that touches the integration. Instead of failing or emailing, redirect the user to your new OAuth consent screen inline. The user sees "authorize this connection" as a natural step in their existing workflow, not as an interruption.

Implementation sketch:

// In your integration middleware
async function getIntegrationClient(userId: string, provider: string) {
  const account = await db.integratedAccounts.findOne({ userId, provider });
 
  if (account.migrated_to_new_platform) {
    return newPlatformClient(account);
  }
 
  // Not yet migrated - check if user is in an interactive session
  if (currentRequestIsInteractive()) {
    // Redirect inline to new OAuth flow
    throw new ReauthRequired({
      provider,
      returnUrl: currentRequestUrl(),
      message: 'One-time reconnection required for security'
    });
  }
 
  // Background job - fall back to old platform until user reconnects
  return oldPlatformClient(account);
}

Background jobs continue running through the old platform. Interactive sessions upgrade the connection when the user is already engaged. Most accounts migrate within 30 days without a single email.

Option 2: Just-in-time email at token expiry

Sort your unmigrated accounts by refresh_token_expires_at. As each token approaches expiry, send a single "reconnect to continue" email to the account admin, timed 7 days before expiry. This keeps the reconnect campaign spread over months instead of all at once.

Option 3: Scheduled coordinated reconnect (highest friction, sometimes required)

For providers where refresh tokens don't expire naturally (Salesforce, HubSpot in certain configurations), passive shadow-consent still works but takes longer. If your outgoing contract has a hard cancellation date, you may need a coordinated reconnect campaign for the last 5-15% of accounts that never triggered interactive sessions.

When you have to do this, script it:

  1. Segment by customer tier. Email enterprise customers via their CSM first.
  2. Send a 14-day heads-up, then a 7-day reminder, then a 24-hour final notice.
  3. Publish a status page entry explaining the migration and the security rationale.
  4. Staff a dedicated support channel for the reconnect window.
  5. Track the reconnect completion rate hourly, not daily.

The single anti-pattern to avoid

Do not run a global "reconnect everything by Friday" email. It signals instability, floods support, and disproportionately churns your smallest customers who have the least patience. Progressive re-auth over 30-60 days is always better than a synchronous reconnect over 3 days.

Schema Mapping and Testing Checklist

Response shape divergence is the number-one reason migrations get rolled back. A structured mapping and diffing process catches 95% of the bugs before they reach production.

When you swap out one unified API for another, your application code is expecting a very specific response shape. Even small differences - a null where you expected [], an ISO 8601 timestamp where you expected epoch millis, a nested email_addresses array where you expected a flat email string - will break code silently.

Work through this checklist per integration:

Field-level mapping audit

  • List every field your application actually reads. Grep for the API response shape in your codebase. You almost certainly only use 30-40% of what the vendor returns.
  • Confirm each field's presence in the new platform's raw provider response. If a field is not in the raw payload, it was synthesized by the old vendor - you will need to derive it in JSONata.
  • Match data types exactly. Old vendor returns "phone": "+1-555-1234", new provider returns "phone": {"number": "+1-555-1234", "type": "work"}. Your JSONata must reshape.
  • Match null handling. null vs undefined vs missing key vs empty string - your consuming code cares. Pick one convention and enforce it in JSONata.
  • Match array ordering. If you were relying on Merge's ordering of related records, note that provider-native ordering will differ. Sort explicitly in JSONata if order matters.

Timestamp and timezone normalization

  • All timestamps in a single format. ISO 8601 UTC is the safe default.
  • Handle provider-specific gotchas. Salesforce dates can come as strings in the org's default locale. HubSpot uses epoch milliseconds. Normalize in mapping.
  • Preserve time zone information when it matters. For scheduling and calendar use cases, keep the original zone alongside a normalized UTC value.

Custom field and remote_data coverage

  • Ensure every custom field your enterprise customers depend on has a mapping. Level 3 (account-level) overrides for one-offs, Level 2 (environment) for systematic ones.
  • Preserve a remote_data escape hatch. Even if your primary mapping covers 100% of current usage, keep the raw provider response accessible so downstream code can access uncommon fields without a new deployment.

Test coverage before cutover

  • Golden-file tests per integration. Capture a known good response from the old vendor per resource type. Snapshot the new vendor's mapped response. Diff.
  • Property-based tests for shape stability. For each mapped field, assert the type and required-ness. Catch schema drift when the provider changes their API.
  • Diff-count budget. Set a threshold: less than 1% of dual-read responses can diverge before cutover is allowed. Enforce it in your CI or in your migration dashboard.
  • Load test the new platform at peak throughput. Don't cut over on a Wednesday afternoon and discover the new platform's rate limit ceiling on Friday morning.
  • End-to-end test one enterprise customer per integration. Not a synthetic tenant - a real customer's data, with their permission, in a sandbox or staging environment.

Migration Effort Estimates by Workstream

Knowing the steps is half the battle. The other half is staffing the work correctly so it doesn't derail your sprint planning for two quarters.

Every migration is different, but after working with teams moving off legacy unified APIs, the effort breaks into predictable workstreams. The estimates below assume a team that already has production integrations running through Merge and is migrating to Truto.

Workstream Scope Estimated Effort Notes
OAuth app registration Create your own OAuth apps in each provider's developer portal 1-2 days per provider Most portals take 30 minutes. Salesforce Connected Apps and Workday tenant registration are the outliers.
Token export and import Extract credentials from Merge, format for Truto's integrated account schema, import via API 2-3 days total Scripted, not manual. Encrypt at rest. Test one provider end-to-end before batching.
JSONata response mappings Write environment-level mappings that mirror your existing Merge response shapes 3-5 days for first 3 integrations, then 0.5-1 day per additional integration The first mapping takes the longest because you are learning JSONata. After that, patterns repeat.
Webhook re-routing Update webhook URLs in provider dashboards, write JSONata transforms for inbound events 1-2 days per provider with webhooks Some providers (e.g., Greenhouse) require admin access to change webhook endpoints. Coordinate with your customers' admins early.
Dual-read validation Run parallel reads, hash-compare responses, log and fix divergences 7-14 days elapsed (low daily effort) Mostly automated. Engineering effort is in fixing the JSONata edge cases that surface during diffing.
Cutover and deprecation Feature-flag the base URL swap, monitor error rates, cancel old contract 1-2 days per integration Keep the old platform live for one week as a rollback path.

For a team with 5 provider integrations and moderate webhook usage, expect roughly 3-4 weeks of total engineering effort spread across 6-8 calendar weeks (to accommodate the dual-read validation window). The calendar time compresses if you can parallelize the OAuth app registration and JSONata mapping work across two engineers.

Info

What drives effort up: Merge-owned OAuth apps (requires a reconnect campaign for those providers), heavy use of Merge's Common Data Model fields that don't map cleanly to raw provider responses, and write-heavy integrations that need sandbox validation before cutover.

What drives effort down: You already own your OAuth apps, your application only uses a small subset of Merge's response fields, and your integrations are primarily read-only.

Post-Migration Monitoring and Rollback Plan

A migration is not complete when the base URL flips. It's complete when the old platform has been offline for two weeks and nothing broke. Instrument accordingly.

The two weeks immediately after cutover are when subtle bugs surface: an edge-case custom field breaks on a customer that only syncs monthly, a webhook signature mismatch fires on a rare event type, a background job hits the new rate limit ceiling for the first time. Plan for it.

The monitoring surface

Instrument these five signals per integration, and alert if any degrade compared to the pre-cutover baseline:

  1. Request success rate. Track 2xx/4xx/5xx breakdown per integration, per endpoint. A sudden 4xx spike usually means a JSONata mapping issue. A 5xx spike usually means a provider-side change or a rate limit ceiling.
  2. P50 and P95 response latency. Compare to the pre-migration baseline. Pass-through architectures should be faster than sync-and-store for read paths, but network topology and region choice can regress this.
  3. Webhook delivery lag. Time between provider event and downstream consumer processing. Should be seconds, not minutes.
  4. Token refresh success rate. If refresh failures spike, you either have an OAuth app misconfiguration or a permission scope regression.
  5. Field-level null rate per resource. If a specific field is suddenly null across all accounts, your JSONata mapping is dropping data.

Rollback plan (keep it warm for 14 days)

A rollback is not a failure - it's a control. Design the migration so you can flip back in under 15 minutes if something breaks.

  • Keep the old vendor contract live for at least 14 days after cutover. Do not cancel on cutover day. The delta between one month of dual billing and one month of firefighting production issues is not close.
  • Feature-flag base URL per integration. Never cut over all integrations in one deploy. One integration at a time, with 24-48 hours between cutovers.
  • Preserve token exports. Keep the encrypted export of tokens in the old platform's format for 30 days. If you need to roll back, you can re-hydrate.
  • Document the rollback runbook. Which env var to flip, which webhook URL to restore, who has approval authority. On a Sunday at 2 AM, no one wants to figure this out from Slack scrollback.
  • Pre-write customer communication templates. If a rollback affects customers, you need the incident update ready before the incident, not during.

The 14-day success criteria

Before you cancel the old contract, confirm all six:

  1. Zero customer-reported issues traceable to the migration.
  2. Request success rate within 0.5% of pre-migration baseline.
  3. P95 latency at or better than pre-migration baseline.
  4. Webhook delivery lag under 10 seconds P95.
  5. Zero JSONata mapping hotfixes in the previous 7 days.
  6. Written sign-off from your security team confirming the outgoing vendor's data deletion has been triggered.

Only then do you cancel the old contract. The relief of stopping the linked-account bill is not worth the tail risk of a rollback you cannot execute.

What to Evaluate Before Signing Anything

Vendor lock-in occurs when the engineering time required to rebuild on top of a vendor's proprietary model makes leaving too expensive. You are effectively held hostage by your own integration success.

Before committing to any replacement, get answers in writing to the questions your future self will care about:

  • Total cost at 200 and 1,000 linked accounts, including overage, enterprise feature uplift, and the engineering time needed to work around platform limitations.
  • Who owns the OAuth client_id for each integration. This is the migration tax that compounds with growth.
  • A live demo with a real Salesforce org that has custom objects. Generic demos hide the pain. Ask to see it live.
  • Data residency and retention policy, in plain language. Region of storage, retention window, deletion SLAs.
  • The programmable escape hatch when the unified schema does not cover a case. Pass-through proxy, raw API access, or declarative override.

Questions to Ask About Connector Maintenance

Pre-built connectors are only as reliable as the team maintaining them. Most vendors won't volunteer this information, so ask directly:

  • What is your SLA for patching a connector when a provider ships a breaking API change? Get a number in hours or business days, not "we prioritize critical issues." A broken Salesforce connector on a Friday afternoon will tell you everything about the real SLA.
  • Can I extend or override a connector's field mappings for a specific customer? If the answer is "file a feature request" or "use passthrough," you will hit this wall within six months of your first enterprise deal.
  • How many connector updates did you ship in the last 90 days, and for which providers? This is a proxy for engineering investment. A stale connector catalog means your team will spend time working around gaps the vendor hasn't fixed.
  • Do you publish a changelog or status page per connector? Without per-connector observability, you're debugging in the dark when a sync breaks.
  • If I leave, can I export my customers' OAuth tokens? This is the single highest-leverage question. If the answer is no - or if the tokens were issued to the vendor's OAuth app - every linked account becomes a reconnect campaign when you migrate. Ask for the exact token custody model in writing before you sign.
  • Can I author custom tools or connectors on the platform, or am I limited to the pre-built catalog? For AI agent use cases, this determines whether you outgrow the platform in months or years.

By leveraging the SaaS integration migration playbook, you can break free from per-account pricing and rigid data models. Truto's zero-integration-specific-code architecture gives you the speed of a unified API with the architectural control of an in-house build.

Stop letting middleware dictate your margins and your product roadmap.

When a Pre-Built Approach Is (and Isn't) the Right Call

Pre-built unified APIs are not categorically bad. They solve a real problem at a specific stage. The mistake is treating a stage-appropriate tool as a permanent architectural choice.

When pre-built works well

  • You need 3-5 standard integrations live in under a month. If your integration surface is narrow - read employees from an HRIS, pull contacts from a CRM - and your customers don't have heavily customized instances, a pre-built connector catalog gets you to market fast.
  • Your integration is not core to your product's value prop. If integrations are a checkbox feature ("yes, we connect to BambooHR") rather than a deep workflow, the lowest-common-denominator data model is usually sufficient.
  • You have zero infrastructure engineers to spare. A fully managed sync-and-store model means no OAuth app management, no webhook infrastructure, and no rate limit handling. That's real value when you're a five-person team shipping your first product.

When pre-built breaks down

  • Your enterprise customers have custom objects and custom fields. The moment a prospect says "we need you to read from our custom Salesforce object," a rigid Common Data Model becomes a liability. If the vendor only supports custom objects for a handful of CRM providers, you're scoping your product's addressable market to match your vendor's coverage.
  • You're building AI agents that need specific tool granularity. Pre-built Tool Packs give every tenant the same tools with the same behavior. If your agent needs a composite action, a provider-specific endpoint, or tenant-scoped field mappings, you'll exhaust the pre-built catalog quickly.
  • Linked-account pricing is eating your margins. Once you cross roughly 100 linked accounts, the per-connection pricing model starts compounding against your unit economics. If your product's growth depends on customers connecting multiple systems, your middleware cost curve steepens faster than your revenue curve.
  • You need real-time data, not cached snapshots. Sync-and-store architectures introduce latency between the source system and your application. For use cases like AI agents acting on live CRM data, alerting pipelines, or approval workflows, polling-interval delays are unacceptable.
  • Your security team won't accept a third-party data processor. Storing a cached copy of your customers' HRIS, payroll, or CRM data in a vendor's database adds a processor to your DPA, a line item to your security review, and a risk factor to your SOC 2 narrative.

The honest assessment: if you're pre-Series B, building your first three integrations, and your customers run vanilla CRM instances, a pre-built unified API is probably the right call. Ship fast, learn what your customers actually need, and migrate when the architecture stops fitting.

But if you're signing enterprise deals, your customers have custom schemas, or your product's AI agents need deep tool access - plan the migration now, not after you've accumulated 500 linked accounts on someone else's OAuth apps.

FAQ

What are the best alternatives to Merge.dev for B2B SaaS integrations?
Merge.dev alternatives fall into three architectural camps. Unified APIs (Truto, Apideck, Finch) offer a single normalized API surface - Truto uses a zero data retention pass-through model with declarative JSONata mappings, while Apideck and Finch are closer to Merge's sync-and-store pattern. Embedded iPaaS platforms (Paragon, Workato Embedded, Tray.io) offer visual workflow builders best suited when your product exposes automation UX to customers. Workflow automation tools (Pipedream, Zapier for Developers) prioritize breadth of app catalog over consistent data models. Pick based on your architectural pattern, not just feature parity.
When should I consider migrating off Merge.dev?
The five concrete triggers are: crossing 150-200 linked accounts (where per-account pricing steepens fastest), losing enterprise deals over custom object or custom field gaps, security team blockers on third-party data processors or residency, AI agent product needing tool granularity the platform doesn't expose, and user-visible sync latency from polling intervals. If two or more apply, the compounding cost of staying already exceeds the one-time migration cost.
Can I transfer OAuth tokens off Merge.dev without customer reconnects?
It depends on OAuth app ownership. If your own client_id is registered in the provider's developer portal, refresh tokens are portable and can be imported directly into a new platform with zero customer friction. If Merge owns the OAuth app, the refresh tokens are non-transferable and you need progressive re-auth. API-key based integrations can rotate silently. Most portfolios have a mix; sequence the migration to tackle transferable providers first.
How do I minimize customer friction during a zero-downtime re-auth?
Use progressive shadow-consent rather than a bulk email campaign. Intercept the next authenticated user action that touches the integration and redirect inline to your new OAuth consent screen. Background jobs continue routing through the old platform until each user re-authorizes naturally during interactive sessions. This spreads the reconnect load over 30-60 days and eliminates the support wave that a synchronous reconnect email produces.
What is the sample migration timeline for moving off Merge.dev?
For a team with five provider integrations and moderate webhook usage, expect 3-4 weeks of engineering effort spread across 6-8 calendar weeks. OAuth app registration takes 1-2 days per provider, token export and import 2-3 days total, JSONata response mappings 3-5 days for the first three integrations then 0.5-1 day per additional, webhook re-routing 1-2 days per provider, dual-read validation 7-14 days elapsed, and cutover 1-2 days per integration. Keep the old contract live for 14 days after cutover as a rollback path.
What are the common pitfalls to avoid when migrating unified API providers?
The biggest pitfalls are: canceling the old vendor contract on cutover day (keep it live for 14 days), running a synchronous reconnect email campaign instead of progressive re-auth, cutting over all integrations in one deploy instead of one at a time, skipping the pre-migration data residency and subprocessor audit, and not diffing responses at the field level before cutover. Response shape divergence (null vs empty array, timestamp formats, array ordering) is the top cause of rollbacks.

More from our Blog