---
title: How to Migrate from Finch to a Multi-Category Unified API
slug: how-to-migrate-from-finch-to-a-multi-category-unified-api
date: 2026-07-03
author: Nachi Raman
categories: [Engineering, Guides]
excerpt: Learn the exact technical playbook to migrate from Finch to a multi-category unified API without forcing enterprise users to re-authenticate.
tldr: "You can migrate from Finch to a multi-category unified API without downtime by extracting OAuth tokens, importing them into a generic credential context, and using declarative JSONata transforms."
canonical: https://truto.one/blog/how-to-migrate-from-finch-to-a-multi-category-unified-api/
---

# How to Migrate from Finch to a Multi-Category Unified API


If you built your initial HRIS integrations on Finch and your product roadmap now demands CRM, ATS, ticketing, or accounting integrations, you are staring at an architectural wall. Finch does one thing exceptionally well: employment data. But when enterprise buyers demand native integrations with their broader software ecosystem, a single-category unified API becomes a hard bottleneck.

The engineering reality is stark. A study by BetterCloud revealed that companies with 1,500 to 4,999 employees use an average of 101 SaaS apps. Your customers do not want your product to exist in a silo. You either integrate a second unified API platform, build point-to-point connections in-house, or migrate to a multi-category provider.

Most engineering leaders delay this migration because of the "re-authentication cliff." Moving to a new integration infrastructure typically means emailing hundreds of enterprise customers, asking their IT admins to log back in, and forcing them to re-authorize OAuth permissions. This process generates support tickets, introduces immediate churn risk, and burns social capital with your best accounts.

You can bypass this entirely. If you approach the migration as a data operation rather than a code rewrite, you can port your existing integrations to a multi-category unified API without your end users ever knowing. 

This guide breaks down the exact technical strategy to export OAuth tokens, import them into a generic credential context, handle rate limits post-migration, map schemas with declarative transforms, and flip traffic - without forcing a single end user to reconnect. For a broader strategic look at expanding your integration categories, see our [Migrating Beyond Finch](https://truto.one/migrating-beyond-finch-expanding-to-a-multi-category-unified-api-without-the-re-authentication-cliff/) guide.

## The Architectural Wall of Single-Category Unified APIs

Starting with a niche unified API makes perfect sense in the early days of a product. If you are building payroll software or an employee engagement platform, you just need to read employee rosters and write back deduction data. Finch's architecture maps this employment data perfectly.

The friction begins when your sales team starts losing deals because your platform cannot sync data to Salesforce, pull candidate profiles from Greenhouse, or push invoices to QuickBooks. 

At this point, engineering teams face the "N+1 Unified API" problem. If you decide to keep Finch for HRIS and adopt a second unified API for CRM, you are now managing multiple vendor SDKs. You have to normalize two different webhook formats. You have to handle two completely different error handling paradigms and pagination strategies. The entire point of a unified API is to abstract away integration complexity, but stringing multiple unified APIs together actively multiplies that complexity.

Multi-category unified APIs solve this by allowing you to build once and connect to multiple software categories through one standardized endpoint and a single execution pipeline. The challenge is getting there.

## Why the Re-Authentication Cliff Stops Migrations

**The re-authentication cliff is the operational risk and customer friction caused when a SaaS company migrates integration infrastructure, forcing all existing users to manually re-authorize their third-party connections.**

When evaluating a migration away from Finch, the technical implementation of the new API is rarely the blocker. The blocker is the customer success nightmare of the migration itself. 

Enterprise IT administrators are notoriously protective of their credentials. When they connected their Workday or Gusto instance to your platform six months ago, it required a security review. If you send an email stating, "We upgraded our systems, please click here to reconnect your HRIS," you trigger a cascade of negative events:

1.  **Direct Churn Risk:** Customers who are on the fence about your product will use the broken integration as an excuse to churn.
2.  **Support Volume Spikes:** IT admins will open tickets asking why the connection broke and demanding new security documentation for the new OAuth app.
3.  **Data Sync Outages:** Until the customer clicks the link, their data stops syncing. Your product appears broken.

Migrating API integrations often requires re-consent flows if tokens are not portable or if scopes change. This makes OAuth token migration the single most critical part of replatforming. 

## How to Migrate OAuth Tokens Without Downtime

The secret to a zero-downtime migration is treating OAuth tokens as highly portable string values rather than proprietary vendor assets. The OAuth 2.0 specification is standardized. An `access_token` and a `refresh_token` generated by Gusto or Rippling do not care if they are stored in Finch's database or a different multi-category platform's database. They only care that they are passed correctly to the upstream API.

To execute this migration, you must export your tokens from your current provider and inject them into a generic credential context in your new platform. 

### The Migration Sequence

Here is the exact architectural flow for porting credentials without touching the end user:

```mermaid
sequenceDiagram
    participant Backend as "Your Backend"
    participant LegacyAPI as "Legacy API (Finch)"
    participant NewAPI as "Multi-Category API"
    
    Backend->>LegacyAPI: Request connection export (Provider, Tenant ID)
    LegacyAPI-->>Backend: Return access_token, refresh_token, expiry
    
    Backend->>NewAPI: POST /credentials/import
    Note right of Backend: Send raw tokens to generic context
    
    NewAPI-->>Backend: Return new Connection ID
    
    Backend->>Backend: Update database with new Connection ID
    Backend->>Backend: Flip traffic flag for this tenant
```

### 1. Exporting the Tokens

First, you need to extract the raw OAuth material. You will need the `access_token`, the `refresh_token`, the `expires_at` timestamp, and the upstream provider identifier (e.g., `workday`, `bamboohr`). 

> [!WARNING]
> Always perform token extraction and importation over secure, encrypted channels. Treat these tokens with the exact same security posture as you would raw user passwords.

### 2. Importing into a Generic Credential Context

Your new multi-category unified API must support bringing your own OAuth apps and importing raw tokens. If the platform forces you to use their centralized OAuth apps, token migration is impossible because the `client_id` and `client_secret` will not match the tokens you hold.

You will hit an endpoint on your new provider to inject the credentials. The payload typically looks like this:

```json
{
  "provider": "bamboohr",
  "tenant_id": "customer_12345",
  "credentials": {
    "access_token": "ya29.a0AfB_by...",
    "refresh_token": "1//0eF_...",
    "expires_in": 3600
  }
}
```

Once the new platform ingests this payload, its internal scheduler takes over. It will use the `refresh_token` to generate a fresh `access_token` shortly before the expiration window. The end user remains completely unaware that the infrastructure handling their API requests has changed.

For a deeper dive into the specific API calls required for this step, review our guide on [How to Migrate from Finch to a Multi-Category Unified API (Without the Re-Authentication Cliff)](https://truto.one/how-to-migrate-from-finch-to-a-multi-category-unified-api-without-re-authenticating-users/).

## Handling Rate Limits and API Pagination Post-Migration

Once your tokens are safely ported and traffic is flipped, your backend will start receiving responses from the new multi-category API. This is where architectural differences between integration platforms become painfully obvious, specifically around rate limiting and backpressure.

### The Reality of Upstream Rate Limits

Every SaaS API enforces rate limits. Salesforce might limit concurrent API requests. BambooHR might limit requests per minute based on the customer's pricing tier. 

Many unified API platforms attempt to "help" developers by silently absorbing HTTP 429 (Too Many Requests) errors. They queue the request, apply an arbitrary backoff, and hold the connection open. This is an architectural anti-pattern. Silent retries hide backpressure from your system, lead to cascading timeout failures in your worker queues, and strip you of the ability to prioritize critical data syncs over background polling.

A robust platform passes HTTP 429 errors directly to the caller. 

When an upstream API returns a 429, Truto passes that error back to your application immediately. However, Truto normalizes the upstream rate limit information into standardized headers per the IETF specification. Regardless of whether the underlying API is HubSpot, Salesforce, or Gusto, you will receive:

*   `ratelimit-limit`: The total number of requests allowed in the current window.
*   `ratelimit-remaining`: The number of requests left.
*   `ratelimit-reset`: The time at which the rate limit window resets.

This gives your engineering team full control. You can implement exponential backoff with jitter directly in your worker processes, utilizing the exact `ratelimit-reset` timestamp to schedule the retry accurately.

```javascript
// Example: Handling normalized rate limits in your worker
async function fetchUnifiedData(url, connectionId) {
  const response = await fetch(url, {
    headers: { 'Authorization': `Bearer ${connectionId}` }
  });

  if (response.status === 429) {
    const resetTime = response.headers.get('ratelimit-reset');
    const waitMs = (new Date(resetTime * 1000).getTime()) - Date.now();
    
    console.warn(`Rate limited. Backing off for ${waitMs}ms`);
    await sleep(waitMs + 1000); // Add 1s jitter
    return fetchUnifiedData(url, connectionId); 
  }

  return response.json();
}
```

## Normalizing Responses with Declarative Transforms

Token migration solves the customer friction problem. But what about your internal engineering friction? Your frontend components and backend database schemas were built to expect Finch's specific JSON output. 

If you migrate to a new multi-category unified API, the shape of the data will change. A `first_name` field might become `employee.name.first`. A `status` field might become `employment_status`. Rewriting your entire application logic to handle the new schema defeats the purpose of a fast migration.

The solution is utilizing a proxy layer that applies declarative transforms to the API responses before they reach your backend.

### The Proxy API Architecture

Instead of hardcoding integration logic, advanced unified APIs route requests through a proxy layer. This layer intercepts the raw response from the upstream provider (or the standard unified model) and applies a JSONata expression to mutate the payload into whatever shape you desire.

**JSONata is a lightweight query and transformation language for JSON data. It allows you to filter, flatten, and reshape complex nested objects without writing integration-specific runtime code.**

By writing a specific JSONata transform, you can force your new multi-category API to output data that perfectly mimics the legacy Finch schema. Your frontend code does not have to change. Your database ingestion scripts do not have to change.

Here is a conceptual example of a JSONata expression mapping a generic unified HRIS response back into a legacy schema format:

```json
/* JSONata Transform: Mimicking Legacy Schema */
{
  "id": employee_id,
  "first_name": profile.name.given_name,
  "last_name": profile.name.family_name,
  "department": employment.department.name,
  "manager": {
    "id": employment.manager.id
  },
  "is_active": employment.status = "ACTIVE" ? true : false
}
```

You upload this declarative mapping to the platform. Every time your backend requests the `/employees` endpoint, the platform fetches the data, applies the JSONata transform in milliseconds at the edge, and returns the exact JSON shape your legacy code expects. 

This decouples the migration of your infrastructure from the refactoring of your application logic. You can migrate the tokens and flip the traffic on day one, and slowly update your internal data models over the next year at your own pace.

## Choosing the Right Multi-Category Unified API

When expanding beyond employment data, you have several architectural paths. If you are evaluating Merge.dev alternatives, you will quickly notice a divergence in how these platforms are built under the hood. 

Many legacy unified APIs rely on hardcoded integration logic. For every new provider (e.g., a new ATS or a niche CRM), their engineers must write custom TypeScript or Python code, deploy it to their workers, and maintain it against upstream API changes. This architecture inherently limits extensibility. It is why you often find yourself waiting months for a vendor to add a specific custom field or support a new endpoint.

The superior architectural pattern relies on zero integration-specific code. 

In this model, the platform operates a generic execution pipeline. The differences between Salesforce, Workday, and Zendesk are not handled by custom `if/else` statements in the runtime logic. Instead, the differences are abstracted entirely into declarative JSON configurations stored in a database. 

When a request comes in, the generic pipeline fetches the declarative mapping for that specific provider, executes the necessary HTTP calls, and applies the JSONata transforms. Because there is zero integration-specific code in the runtime, adding support for a new category or a custom enterprise field becomes a pure data operation. You are not waiting on a vendor's engineering sprint; you are simply updating a mapping configuration.

This architecture makes the platform inherently more extensible across multiple categories. It is the only way to reliably support the long tail of 100+ SaaS applications your enterprise customers actually use.

## Strategic Next Steps for Your Migration

Migrating away from a single-category unified API like Finch is a necessary step as your product moves upmarket. The enterprise ecosystem demands interoperability across HRIS, CRM, ATS, and accounting systems. 

Do not let the fear of the re-authentication cliff hold your product roadmap hostage. By exporting your OAuth tokens, importing them into a generic credential context, handling rate limits intelligently, and using declarative JSONata transforms to mimic your legacy schemas, you can execute a zero-downtime migration.

Treat your integrations as data operations, not code rewrites. Maintain ownership of your OAuth applications, demand transparent rate limit handling, and choose an architecture built on a generic execution pipeline rather than hardcoded integration scripts.

> Ready to expand your integration roadmap beyond HRIS? Truto's multi-category unified API gives you zero integration-specific code, full OAuth token portability, and declarative JSONata transforms to make your migration painless. Talk to our engineering team today.
>
> [Talk to us](https://cal.com/truto/partner-with-truto)
