The Apideck Migration Playbook: Switch Unified APIs Without Re-Authenticating Users
A technical playbook for engineering leaders to migrate from Apideck to a new unified API without forcing enterprise customers to reconnect their SaaS integrations.
If you are evaluating Apideck alternatives in 2026, you are likely staring down a familiar set of scaling walls. The consumer-based pricing curve no longer matches your unit economics, the 24-hour polling on virtual webhooks is creating customer support tickets, and you are trying to avoid the ultimate failure condition: asking hundreds of enterprise customers to re-authenticate their Salesforce, HubSpot, or BambooHR accounts.
Forcing users to click "Reconnect" generates support tickets, introduces immediate churn risk, and burns social capital with your best accounts. The thought of executing a forced re-authentication migration is enough to keep engineering leaders up at night.
You do not have to do this. You can migrate away from Apideck without asking a single end user to reconnect. The process involves exporting OAuth tokens from Apideck Vault, importing them into your new platform's credential context, mapping the old unified schema to the new one, and updating your API routing so your frontend code stays completely untouched.
This playbook walks through the exact architectural decisions, OAuth token extraction steps, declarative schema mapping strategy, and rate limit handling required to switch providers cleanly. It is written for senior PMs and engineering leaders who already understand the basics (if you need to draft an internal spec, see our template on how to create an Apideck-to-Truto migration guide). We will skip the marketing fluff and go straight to the trade-offs, the gotchas, and the code. For a deeper dive specifically on credential extraction, see our companion guide on how to migrate from Apideck without re-authenticating end users.
The Vendor Lock-In Trap: Why SaaS Teams Outgrow Apideck
Apideck is a well-built product for early-stage teams. The documentation is clean, the Vault connection UI is polished, and the real-time pass-through architecture that avoids caching customer data is a sound design decision that we share at Truto. Early-stage teams ship integrations on Apideck in days instead of quarters, and that velocity is worth a lot when you are racing competitors.
Integrations are a mandatory requirement for B2B SaaS vendors, not a backlog item. The average B2B organization uses over 130 SaaS applications, according to Encanvas research. Zylo's 2026 SaaS Management Index reveals that large enterprises add an average of 21 new applications per month. Every new app in your customer's stack is a potential integration request landing on your roadmap. Building these connections in-house is prohibitively expensive, with custom integration development costs routinely ranging from $50,000 to $500,000 depending on complexity and compliance needs.
While Apideck helps teams get off the ground quickly to meet this demand, engineering leaders typically hit specific scaling limits that force a migration conversation:
1. Consumer-based pricing models punish scale. Apideck publicly shifted from API call-based to consumer-based pricing. This model scales costs based on the number of active end customers you have connected, rather than your actual API volume. That model can work when your customers are large and few, but it breaks down quickly if you are a PLG product onboarding hundreds of small connections, or if your enterprise customers each have multiple subsidiary connections counted as separate consumers. As your SaaS product grows, your integration infrastructure costs inflate linearly, even if those users only sync data once a month. Cost scales with logos, not with usage.
2. Virtual webhooks default to long polling intervals. Apideck simulates real-time events by monitoring enabled resources at regular intervals, typically polling every 24 hours for provider events. Modern SaaS workflows demand real-time reactivity. For a CRM where a sales rep just updated a deal, a one-day delay is not "real-time" by any stretch. Waiting a full day for a webhook event to trigger a downstream action is unacceptable for use cases like real-time lead routing or instant payroll syncing. Your customers expect updates within minutes.
3. Proprietary unified models restrict custom object access.
When enterprise customers customize their Salesforce or HubSpot instances with unique fields, rigid unified schemas break. The moment a Salesforce admin creates a Project__c object with custom fields, the strict unified model returns nothing useful. If the provider's unified model does not explicitly support a custom object, you are locked out of that data. You end up writing one-off integration code anyway, which defeats the entire purpose of paying for a unified API.
Apideck Alternatives: Evaluating the 2026 Unified API Landscape
When you decide to migrate, you need to evaluate the market carefully to avoid trading one set of constraints for another. Before committing to a migration, get clear on what you are optimizing for. The 2026 integration landscape splits into a few distinct architectural approaches.
Evaluate your options along these four critical dimensions:
| Dimension | What to Ask During Evaluation |
|---|---|
| Data retention | Does the vendor cache customer data, or is it a stateless pass-through? Pass-through is mandatory for HIPAA, SOC 2 strict scopes, and GDPR-sensitive workloads. |
| Pricing model | Is it per-consumer, per-connection, per-API-call, or a flat platform fee? Model the 24-month cost curve at your projected scale to avoid another pricing trap. |
| Schema flexibility | Can you map custom objects without filing a support ticket? Can you override the unified schema per-customer when standard models fail? |
| OAuth app ownership | Do you own the OAuth client credentials, or does the vendor? This determines whether you can ever leave without re-authenticating users. |
Merge.dev and the Linked-Account Limit
Merge positions itself as a direct unified API competitor to Apideck, offering deep category coverage and a polished developer experience. However, they rely heavily on linked-account limits and usage-based restrictions that can punish scale just as severely as Apideck's consumer model. Furthermore, Merge defaults to a sync-and-cache architecture, meaning they store your customers' third-party data on their servers. This introduces massive compliance overhead for SOC 2, HIPAA, and GDPR.
Paragon and Embedded iPaaS
Paragon positions itself as an embedded iPaaS alternative for teams that need visual workflow engines rather than just declarative APIs. If your product team wants to drag and drop logic boxes on a canvas, Paragon is a strong option. However, visual builders create massive technical debt for engineering teams. Version control is difficult, debugging a visual canvas in production is a nightmare, and you are entirely locked into their proprietary execution runtime.
Truto and the Declarative Pass-Through Architecture
Truto takes a fundamentally different approach. We utilize a zero-integration-specific-code architecture. Integrations are defined purely as data—using JSONata expressions to map provider schemas to a unified model. We do not store your customers' payload data. We act as a stateless proxy, passing requests directly to the downstream provider. This satisfies strict enterprise compliance requirements while giving developers the predictability of a code-first deployment model.
The Zero-Downtime Apideck Migration Playbook
The secret to migrating integration providers without downtime relies on a single architectural principle: OAuth app ownership.
If you used your own client ID and client secret when setting up Apideck (meaning you registered the OAuth application directly in Salesforce, HubSpot, Google, etc.), you own the relationship with the downstream provider. Apideck is simply holding the access tokens and refresh tokens on your behalf. Your customers granted access to your app, not Apideck's.
Because you own the OAuth application, the authorization grants tied to those tokens belong to you. You can extract them, move them to a new credential context, and continue making API calls without the end user ever knowing the underlying infrastructure changed.
Important: If you used Apideck's shared OAuth credentials for your integrations, you do not own the authorization grants. In that scenario, users must re-authenticate. Always use white-labeled OAuth apps for customer-facing integrations. For more context, read our guide on OAuth App Ownership Explained.
The migration breaks into four distinct phases. Done correctly, the end user experiences zero disruption.
flowchart LR
A[Phase 1<br>Export OAuth tokens<br>from Apideck Vault] --> B[Phase 2<br>Import credentials<br>into new platform]
B --> C[Phase 3<br>Map old unified schema<br>to new responses]
C --> D[Phase 4<br>Cutover API routing<br>via feature flag]
D --> E[Decommission Apideck<br>after burn-in window]The core contract you are preserving is the shape of API responses your frontend already consumes. If your React app expects a specific JSON structure from a CRM contacts call, the new provider must return that exact same shape. Customers see no difference, and your engineers do not have to refactor a single component.
Step 1: Exporting OAuth Tokens from Apideck Vault
The first technical step is extracting your existing credential state. Apideck Vault stores the access tokens, refresh tokens, scopes, and metadata required to authenticate requests against third-party APIs. You need to programmatically iterate through your Apideck consumer list and extract the connection details for every active integration.
The Extraction Process:
- Query the Apideck Vault API to list all consumers (your end users).
- For each consumer, fetch their active connections.
- Extract the
access_token,refresh_token,expires_intimestamp, and any provider-specific metadata. - Map this data to your new provider's credential schema and inject it via their connection creation endpoint.
sequenceDiagram
participant Backend as Your Backend
participant Apideck as Apideck Vault
participant Truto as Truto API
Backend->>Apideck: GET /vault/consumers
Apideck-->>Backend: List of Consumers
loop For each Consumer
Backend->>Apideck: GET /vault/connections/{consumer_id}
Apideck-->>Backend: Connection Data (Tokens, Expiry)
Backend->>Backend: Transform to Truto Integrated Account Schema
Backend->>Truto: POST /integrated-accounts<br>(Inject Tokens & Metadata)
Truto-->>Backend: Success (New Integrated Account ID)
endA simplified TypeScript export script looks like this:
import { Apideck } from '@apideck/node';
const apideck = new Apideck({
apiKey: process.env.APIDECK_API_KEY!,
appId: process.env.APIDECK_APP_ID!,
});
async function exportConsumerCredentials(consumerId: string) {
const connections = await apideck.vault.connectionsAll({
consumerId,
});
return connections.data.map((conn) => ({
consumer_id: consumerId,
service_id: conn.service_id, // 'salesforce', 'hubspot', etc.
unified_api: conn.unified_api, // 'crm', 'hris', etc.
access_token: conn.settings?.access_token,
refresh_token: conn.settings?.refresh_token,
expires_at: conn.settings?.expires_at,
instance_url: conn.settings?.instance_url,
metadata: conn.metadata,
}));
}When executing this extraction, keep these hard-won details in mind:
- Refresh tokens have provider-specific TTLs. Salesforce refresh tokens generally do not expire unless revoked, but Google OAuth refresh tokens can expire if unused for six months. Migrate while tokens are warm.
- Some providers rotate refresh tokens on every use. Microsoft Graph and Xero both do this. The instant you call refresh on the new platform, the old Apideck-stored token becomes invalid. Plan the cutover so both systems are not refreshing simultaneously.
- Tenant metadata is non-negotiable. A Salesforce access token without the
instance_urlis useless. A QuickBooks token withoutrealmIdcannot make a single API call. Validate every field before import.
When injecting these tokens into Truto, the platform immediately takes over the token lifecycle. Truto evaluates the expiry timestamp. If the token is near expiration, the platform schedules work ahead of token expiry to execute a refresh grant against the provider using your configured client credentials. This handoff is entirely transparent to the end user.
Refresh token rotation is the silent killer. If your new platform refreshes a Microsoft or Xero token while Apideck still holds the old one, you have just invalidated the old environment. Always run the import in a dry-run mode that does not auto-refresh, then cut over deliberately.
Step 2: Mapping the Unified Schema to Your New Provider
Extracting tokens solves the authentication problem. Now you must solve the data contract problem.
Your frontend and backend systems currently expect JSON payloads formatted according to Apideck's unified schema. Every unified API uses slightly different field names, casing, and nesting. Apideck's CRM contact model is not bit-identical to anyone else's. If you naively swap the backend to a new provider, your frontend breaks in a hundred small places. Rewriting your entire application layer to accommodate a new schema is risky and time-consuming.
Instead of changing your application code, you should use a declarative transformation layer that takes the new platform's response and reshapes it into the exact Apideck contract your application already expects.
Truto handles this via our 3-level JSONata override architecture. You can intercept the response from the provider and transform it before it reaches your application. We use JSONata because it is purpose-built for JSON-to-JSON transformation and runs without deployable code.
Example: Mimicking an Apideck Contact Payload
Let's say your application expects an Apideck-formatted Contact object:
{
"data": {
"id": "12345",
"first_name": "Jane",
"last_name": "Doe",
"emails": [
{
"email": "jane@example.com",
"type": "primary"
}
]
}
}You can write a JSONata expression in Truto to transform the raw provider response into this exact structure. You apply this expression at the Environment level, ensuring that every API call routed through your new infrastructure returns the legacy Apideck shape.
{
"data": {
"id": id,
"first_name": first_name,
"last_name": last_name,
"emails": email_addresses.{
"email": value,
"type": type
},
"phone_numbers": phones.{
"number": number,
"type": category
},
"company_id": account.id,
"custom_fields": $merge([custom_attributes]),
"created_at": $toMillis(created_time),
"updated_at": $toMillis(modified_time)
}
}By utilizing this declarative transformation layer, your frontend components and backend database schemas remain completely untouched. The migration becomes a pure infrastructure swap. Because mappings are stored as configuration rather than code, you can also override them per customer when an enterprise tenant insists on a non-standard field shape. We covered this pattern in detail in our 3-Level API Mapping post.
Step 3: Handling Rate Limits Post-Migration
One of the most dangerous hidden traps in unified API migrations is how rate limits are handled. Different platforms handle rate limits in radically different ways, and your retry logic almost certainly assumes the behavior of the vendor you are leaving.
Many integration platforms silently swallow HTTP 429 (Too Many Requests) errors. They attempt to queue or arbitrarily retry requests on your behalf using hidden exponential backoff algorithms. This sounds helpful until a critical webhook event is delayed by four hours because the vendor's internal queue stalled, or until your application receives a generic 500 error because the vendor's retry loop timed out. Your code never sees the rate limit, never backs off intelligently, and your customer's third-party account hits an extended throttle because the vendor kept hammering it.
Truto takes a radically transparent approach to rate limits. We do not retry, throttle, or apply backoff on rate limit errors. When an upstream API returns an HTTP 429, Truto passes that error directly to the caller.
Normalizing IETF Rate Limit Headers
To give you total control over your execution flow, Truto normalizes upstream rate limit information into standardized headers per the IETF specification. Regardless of whether you are calling a legacy SOAP API or a modern REST endpoint, you will receive consistent headers:
ratelimit-limit: The maximum number of requests permitted in the current window.ratelimit-remaining: The number of requests remaining in the current window.ratelimit-reset: The time at which the current rate limit window resets.
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
ratelimit-limit: 1000
ratelimit-remaining: 47
ratelimit-reset: 12
{
"error": "rate_limit_exceeded",
"message": "Upstream provider rate limit reached."
}Those three headers give you everything you need to implement exponential backoff with jitter on the caller side. This is intentional. The caller knows whether a given request is interactive (a user is waiting) or batch (an overnight sync), and the appropriate retry strategy differs by context. A platform that decides for you will always be wrong some percentage of the time.
async function callWithBackoff(fn: () => Promise<Response>, maxAttempts = 5) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
const res = await fn();
if (res.status !== 429) return res;
const reset = Number(res.headers.get('ratelimit-reset') ?? 1);
const jitter = Math.random() * 500;
await new Promise((r) => setTimeout(r, reset * 1000 + jitter));
}
throw new Error('Rate limit exhausted');
}By passing these headers through, your engineering team can implement precise, application-aware circuit breakers and retry queues. For a deeper take, our post on handling API rate limits across multiple third-party APIs covers the full strategy.
Step 4: Cutover API Routing via Feature Flag
Migrations succeed or fail in the first two weeks. The teams that get this right cut over behind a feature flag at the per-customer level rather than flipping a global switch.
Run a parallel-traffic POC before cutover. Pipe 5% of production read traffic to the new platform, compare responses against Apideck, and only flip the switch when diffs are zero on critical fields. This catches schema mismatches before they become customer-facing bugs.
Build a schema diff harness that compares old vs. new responses on every endpoint. The hardest part is not the engineering—it is the discipline to do the schema diff work before routing live traffic. Once the parallel-traffic validation confirms a 100% match on your critical fields, you can safely route all traffic to the new infrastructure and decommission Apideck after a brief burn-in window.
Why Truto is the Ultimate Apideck Alternative for Enterprise SaaS
Migrating integration infrastructure is a heavy lift, but staying on a platform that limits your growth is fatal for enterprise SaaS companies. As you evaluate your exit strategy, Truto offers a distinct architectural advantage for teams that need deep, reliable, and compliant integrations (for a deeper feature-by-feature breakdown, see our full comparison of Truto vs Apideck).
1. Zero Integration-Specific Code Truto's architecture eliminates the need to maintain fragile TypeScript or Python scripts for every new connector. Integrations are shipped as pure data configurations via declarative JSONata mappings. Schema drift is handled by editing config, not waiting on a vendor sprint.
2. The Proxy API for Custom Objects When a unified model falls short, Truto does not lock you out. Our Proxy API allows developers to bypass the unified schema entirely. You can make raw, authenticated requests to any provider endpoint, including highly customized enterprise Salesforce objects or undocumented beta features, all while utilizing Truto's token management and normalized pagination.
3. Pass-Through Architecture With no customer data persistence (beyond ephemeral processing), Truto keeps SOC 2 and HIPAA scopes perfectly clean. Custom SaaS integration development costs are high enough without adding the ongoing data residency and breach-surface costs of caching everything on a third-party server.
4. Real-Time Unified Webhooks Truto supports real-time inbound webhooks directly from providers that support them, with polling fallback only for providers that genuinely do not. We handle the provider-specific signature verification, normalize the payload using JSONata, and deliver a standardized event to your infrastructure. You are not forced to wait for 24-hour polling loops.
Escaping vendor lock-in requires a clear technical strategy and a platform built for scale. By extracting your tokens, mapping your schemas declaratively, and taking control of your rate limits, you can swap your integration engine without your customers ever noticing.
FAQ
- Can I migrate from Apideck without forcing users to reconnect their accounts?
- Yes, but only if you own the OAuth application registered with each third-party provider. When you own the OAuth app, refresh tokens are portable: you can export them from Apideck Vault and import them into a new platform without the end user ever seeing a reconnect prompt.
- How does Apideck's consumer-based pricing affect costs as I scale?
- Apideck bills based on the number of active end customers connected rather than API call volume. This punishes PLG products with many small connections and enterprise products where each subsidiary counts as a separate consumer. Costs scale with logos, not usage, which often breaks unit economics at growth stage.
- What happens to rate limits when I switch unified API providers?
- Behavior varies widely. Some platforms silently retry 429s internally, hiding rate limit issues from your code. Truto passes 429 errors straight through and normalizes upstream rate limit information into IETF-standard headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset), leaving retry and backoff strategy to the caller.
- How do I handle custom Salesforce objects after migrating from Apideck?
- Strict unified schemas cannot represent custom objects like Project__c or custom fields. The standard solution is a Proxy API that exposes the raw provider endpoint with authentication and rate limit handling already applied, letting you query custom objects without writing per-customer integration code.