Skip to content

Migration Playbook: From Make.com Prototypes to Native SaaS Integrations

A step-by-step architectural runbook for migrating customer-facing integrations from Make.com to native, multi-tenant unified APIs without causing downtime.

Uday Gajavalli Uday Gajavalli · · 15 min read
Migration Playbook: From Make.com Prototypes to Native SaaS Integrations

Your enterprise prospect just finished a great evaluation. They love your product's core functionality, and the UI is exactly what their team needs. Then they ask the inevitable question: "How does this connect to our Salesforce instance?" You point them to a Make.com scenario template or a Zapier link. The deal stalls. The internal champion ghosts you. Six weeks later, procurement picks the competitor with native Salesforce sync built directly into their settings page.

If your B2B SaaS product is still pointing enterprise customers at a Make.com scenario template to handle Salesforce, HubSpot, or NetSuite sync, you have a finite runway before that decision starts costing real ARR. Early-stage SaaS teams often use Make.com to prototype integrations quickly. It is an exceptional platform for internal operations and citizen developers. But as your product moves upmarket, relying on visual workflow builders for multi-tenant data sync becomes a severe architectural liability, which is why B2B SaaS needs native integrations over visual workflows.

This playbook is a step-by-step operational and architectural runbook for senior product managers and engineering leaders who shipped a Make.com prototype to validate demand, watched it work, and now need to migrate that workflow into a native, multi-tenant, white-labeled product feature—without breaking the customers already running on it.

The migration is mostly an architectural transition: from a per-operation visual graph that lives outside your product, to a declarative, code-thin integration layer that lives inside it. Done right, you ship faster, kill a recurring cost line, and stop losing deals to procurement teams that refuse to onboard a second vendor.

The MVP Trap: When Make.com Prototypes Start Costing You Enterprise Deals

Integration readiness is no longer a roadmap item; it is a primary go-to-market requirement.

Make.com is genuinely excellent for what it was built for. Visual workflows, fast iteration, a giant module library, and a free tier that lets a non-engineer prototype a Salesforce-to-Slack flow in an afternoon. That speed is exactly why so many early-stage SaaS teams use it as a customer-facing shim. "We support HubSpot—here's the template."

Then the scaling pain hits, and volume happens.

Relying on third-party workflow tools for customer-facing integrations creates massive onboarding friction. 63% of companies invest in integrations specifically to improve customer retention, and enterprise buyers expect native, white-labeled experiences. When you force a customer to leave your app, create a Make.com account, manage their own OAuth tokens, and debug their own data pipelines, you are externalizing your product's complexity onto the buyer.

Beyond the user experience, the financial reality of this architecture is punishing. The pricing model that felt cheap at MVP starts behaving very differently at scale. On August 27, 2025, Make.com officially switched its billing system from operations to credits, and while this may seem like a simple renaming at first, the change has deeper implications especially for teams using AI modules or working at scale. The November 2025 update added a 25% markup on extra-operation packs over included credits, which means the moment a tenant burns past your provisioned credits, you eat the overage.

The killer is polling. A trigger checking for data every minute will use over 43,000 operations per month just for the check itself, before any actions are even performed. Multiply that across every tenant that wants "near real-time" CRM sync and your COGS for a single workflow can exceed the margin on the entire seat. If a customer syncs 10,000 CRM contacts daily, your integration margins instantly evaporate.

Meanwhile, the alternative—building and maintaining custom API integrations in-house—is equally dangerous. A 2025 analysis by Gartner estimated that mid-market SaaS companies spend roughly 18 to 24 percent of their engineering capacity just maintaining API integrations.

The iPaaS and workflow automation market is exploding. The iPaaS market grew by 23.4% to $8.5 billion in 2024, driven by rising adoption of AI, no-code/low-code developer tools, and SaaS, ranking as the second fastest-growing segment in the application and infrastructure middleware market. Grand View Research projects the global iPaaS market size to reach USD 71.35 billion by 2030, growing at a CAGR of 32.3%.

But enterprise SaaS companies are shifting their spend away from generic workflow tools and toward embedded integration infrastructure. A meaningful chunk of that growth is embedded iPaaS and unified API spend—the layer that sits inside SaaS products, not next to them. You need a way to build native integrations that feel like a natural extension of your product, without dedicating a quarter of your engineering team to API maintenance.

Warning

If more than ~20% of your active customers depend on a Make.com scenario you maintain on their behalf, you are already running a shadow integration platform. Migrate before it becomes a support cost center.

Architectural Differences: Internal Workflows vs. Customer-Facing Integrations

The core confusion that traps PMs is treating an iPaaS like Make.com as interchangeable with an embedded integration layer. As we've detailed in our breakdown of why visual workflows can't replace native product integrations, they are not the same category of tool.

The Make.com Architecture (Point-to-Point Visual Logic)

Internal workflow automation (Make, Zapier, n8n) is designed for a single tenant—your ops team—to wire together heterogeneous APIs into a procedural graph. It is built on point-to-point visual logic. If you want to sync contacts from HubSpot and Salesforce into your app, you build two entirely separate scenarios.

  • State Management: The customer often owns the authentication state. If a token expires, the scenario breaks silently until the user logs into Make.com to fix it.
  • Data Transformation: Logic is trapped inside visual nodes. Transforming a Salesforce Lead into your app's User object requires clicking through UI mappers, making version control, code reviews, and CI/CD rollouts impossible.
  • Execution: Every API call, data transformation, and conditional branch counts as a billable operation. The mental model is "a flowchart that runs."

The Unified API Architecture (Declarative and Embedded)

Customer-facing integration infrastructure has a different shape entirely. Modern SaaS products use declarative Unified APIs to deliver native experiences. Instead of building separate code paths or visual workflows for each provider, you build one integration against a single, normalized common data model.

It must be:

  • Multi-tenant by default, with strict data isolation between customers.
  • White-labeled, so the OAuth consent screen, connection UI, and error states all read as your product.
  • Programmatically managed, so a new tenant connection does not require a human cloning a scenario.
  • Declarative, so a connector update propagates to every tenant without redeploying logic per customer.
  • Observable at the tenant level, not the workflow level.

The declarative model is the architectural shift that matters. Instead of a visual graph encoding "when X happens in HubSpot, do Y in our app," you describe the shape of the integration once—auth flow, endpoints, field mappings, pagination, webhooks—and the runtime executes it identically for every tenant. There is no per-customer scenario to edit. Compare this to an embedded iPaaS versus unified API decision before you commit to either side.

graph TD
    subgraph Make.com Prototype Architecture
        A[Your SaaS App] -->|Webhook| B(Make.com Scenario 1)
        A -->|Webhook| C(Make.com Scenario 2)
        B -->|Custom Mapping| D[Salesforce API]
        C -->|Custom Mapping| E[HubSpot API]
    end

    subgraph Native Unified API Architecture
        F[Your SaaS App] -->|Standardized REST/GraphQL| G{Unified API Layer}
        G -->|Normalized Payload| H[Salesforce API]
        G -->|Normalized Payload| I[HubSpot API]
    end
    
    style A fill:#f9f9f9,stroke:#333,stroke-width:2px
    style F fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px
    style G fill:#fff3e0,stroke:#ff9800,stroke-width:2px

Phase 1: The Migration Audit and Mapping Strategy

Migrating active customers off a legacy workflow tool requires precision. Do not write a single line of code until you have completely audited your existing Make.com footprint. Most teams discover their Make footprint is bigger and messier than they remembered.

Step 1: Inventory the Triggers and Polling Intervals

Build a scenario inventory. Export every active scenario via the Make API. Open your Make.com dashboard and catalog how data currently enters the workflow. For each one, record:

  • Tenant ID it belongs to
  • Trigger type (webhook, polling, scheduled)
  • Source and destination apps
  • Modules used, in order
  • Approximate monthly operation count
  • Last error timestamp and rate

Are you relying on scheduled polling (e.g., "Watch Records" modules that run every 15 minutes)? Or are you relying on inbound webhooks from the third-party provider? Polling in Make.com consumes massive amounts of operations. When migrating to a native architecture, you should transition to webhook-driven architectures wherever the upstream provider supports it. Document the exact event types (e.g., contact.created, deal.updated) that trigger your current workflows.

Step 2: Group Scenarios and Extract Transformation Logic

Group scenarios into integration archetypes. You will almost certainly find that 80% of your scenarios collapse into 4-6 patterns: "sync contacts from CRM," "push events to ticketing," "pull deal updates," "create user on signup," and so on. These archetypes are what you migrate, not the individual scenarios.

Visual workflow builders hide complexity inside configuration modals. You must extract this logic into a format your engineers can actually read. For every module in a scenario, decide whether it becomes:

  1. A field in a unified data model (contact.email, deal.amount)
  2. A normalized webhook event (record.created, record.updated)
  3. A passthrough API call (rare, for custom objects)
  4. Business logic that belongs in your product, not in the integration layer

Category 4 is the one teams miss. Make encourages stuffing business logic into the graph—branching, formatting, conditional routing. That logic does not belong in your integration layer. It belongs in your application, behind your domain model, where it is testable and version-controlled. Document required fields, custom fields, and conditional routing rules.

Step 3: Define the Unified Data Model and Cost Baseline

Once you have extracted the point-to-point logic from Make.com, define the ideal schema for your application. If your app needs a generic Customer object, define that schema once. You will map all upstream providers (Salesforce, HubSpot, Pipedrive) to this single schema in the next phase.

Finally, quantify the cost baseline. Sum the operations per tenant per month and multiply by your current Make credit cost. This is the number you will compare against the native-build cost when you write the business case. For a fuller view of the build-versus-buy math, the true cost of building SaaS integrations in-house breakdown is worth pairing with this audit.

Tip

Stop building point-to-point mappings. The goal of this migration is not to recreate 50 Make.com scenarios as 50 custom Node.js microservices. The goal is to replace 50 scenarios with one native integration powered by a single Unified API data model.

Phase 2: Replacing Point-to-Point Logic with a Unified API

To scale enterprise integrations, you must separate the integration layer from your core business logic. This is where the migration earns its ROI. Every Make scenario that talks to HubSpot, Salesforce, Pipedrive, or Zoho is a point-to-point connection to one provider. Native integrations built on a unified API collapse all of those into one normalized interface.

The pattern to internalize: integration behavior is data, not code.

The Power of JSONata for Data Transformation

Instead of maintaining brittle visual mappers, modern integration platforms use JSONata—a lightweight query and transformation language for JSON data. JSONata allows you to map provider-specific payloads into your unified schema without writing custom code. A connector for a CRM should be a declarative blob—auth config, endpoint definitions, field mappings. The same runtime executes it for every provider. There is no if (provider === 'hubspot') branch anywhere in your stack.

For example, transforming a messy HubSpot contact into your clean, unified Customer schema looks like this in JSONata configuration:

{
  "id": $string(hs_object_id),
  "first_name": properties.firstname,
  "last_name": properties.lastname,
  "email": properties.email,
  "phone": properties.phone,
  "company_name": properties.company,
  "created_at": properties.createdate,
  "updated_at": properties.lastmodifieddate
}

By leveraging zero integration-specific code, your engineering team treats API connectors as data-only operations. You store these JSONata expressions as configuration. When your app requests a customer list from Salesforce, the unified engine fetches the Salesforce data, applies the Salesforce-specific JSONata mapping, and returns the exact same Customer schema you get when querying HubSpot.

Your application code never sees the provider-specific payload. It calls a single endpoint:

const contacts = await truto.unified.crm.contacts.list({
  integratedAccountId: tenant.crmAccountId,
  pageSize: 100,
});
 
// Same shape regardless of whether the tenant is on HubSpot,
// Salesforce, Pipedrive, Zoho, or Close.
for (const contact of contacts.results) {
  await db.upsertContact({
    externalId: contact.id,
    email: contact.email,
    name: `${contact.first_name} ${contact.last_name}`,
  });
}

What replaces a Make scenario that had a polling trigger, three filter modules, a router, two HTTP modules, and an iterator? A single typed function call against a normalized endpoint, with the provider-specific quirks pushed down into declarative configuration that ships once and runs for every tenant.

Handling Custom Fields at Scale

Enterprise customers heavily customize their CRMs. A Make.com template breaks the moment a customer adds a mandatory custom field to their Salesforce instance that your template does not account for.

When migrating to a native architecture, implement a dynamic proxy layer. Keep your unified data models thin. If a customer needs a custom field that does not fit the unified shape, expose it through a passthrough or proxy call rather than bloating the canonical model. Per-customer field overrides should be configuration, not branches in your application code. A unified API should allow you to bypass the strict unified model when necessary, querying the provider's raw API directly while still utilizing the platform's managed authentication and rate limiting. The deeper mechanics are in how do unified APIs handle custom fields.

Phase 3: Handling Auth, Rate Limits, and Webhooks in Production

This phase is where most migrations stall. Make.com abstracts away the harsh realities of distributed systems. When you migrate to a native architecture, you must handle authentication, rate limits, and asynchronous events properly on your own (or outsource them to your integration platform).

1. Managing the OAuth Lifecycle Natively

Enterprise security teams despise third-party OAuth apps they do not recognize. In Make, the user's OAuth connection lives in the scenario. In your native product, the OAuth app is yours and the tokens belong to your tenant records. Three things must work without human intervention:

  1. Refresh ahead of expiry: Tokens should be refreshed shortly before they expire, not lazily on the next 401. A unified API platform should schedule this automatically per integrated account.
  2. Handle revocation: When a user revokes access on the provider side (e.g., via their IT department), surface that to your product UI so the customer sees a "reconnect" prompt rather than silent sync failure.
  3. Own the OAuth app: If you do not own the OAuth client credentials, you are locked into your provider. Read OAuth app ownership explained before signing any contract. To deliver a native experience, you must use a white-labeled Link UI where the customer clicks "Connect Salesforce" inside your application and sees your company logo.

2. Radical Transparency for API Rate Limits

Make.com often handles rate limits by silently pausing execution or failing scenarios entirely, leaving your users confused about missing data. Most engineers do not realize how much retry logic they were inheriting.

When building native integrations, you must architect for failure. However, a common mistake is assuming a unified API platform will magically absorb all rate limit errors for you.

Here is the objective reality of rate limits: A robust unified platform like Truto does not retry, throttle, or apply backoff on rate limit errors automatically. When an upstream API like Salesforce returns an HTTP 429 Too Many Requests, Truto normalizes the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. Truto then passes that 429 error directly to your application.

This is a deliberate architectural decision. The caller (your application) is entirely responsible for retry and exponential backoff logic. Why? Because swallowing HTTP 429 errors at the proxy layer leads to distributed system gridlock and prevents your application from prioritizing critical workloads over background syncs. By exposing normalized headers, your engineering team retains full control over queue management.

In practice your client looks like this:

async function fetchWithBackoff(call) {
  let attempt = 0;
  while (attempt < 5) {
    const res = await call();
    if (res.status !== 429) return res;
 
    const reset = Number(res.headers.get('ratelimit-reset')) || 2 ** attempt;
    await sleep(reset * 1000);
    attempt++;
  }
  throw new Error('Exhausted retries');
}

Owning this makes per-tenant behavior debuggable. For a deeper treatment, see best practices for handling API rate limits across multiple third-party APIs.

3. Normalizing Inbound Webhooks

Make.com provides generic webhook URLs, but you are responsible for parsing the specific payload shape of every single SaaS provider. Make handles each provider's webhook signature, payload shape, and retry behavior inside the module. Your native integration must do the same and expose a single canonical event stream to your application.

A native architecture standardizes webhook ingestion. The pattern:

  • One ingestion endpoint per provider, with signature verification.
  • A declarative mapping (using JSONata) from the provider's raw event payload to your canonical record:created, record:updated, record:deleted shape.
  • A signed outbound webhook to your application's listener with at-least-once delivery semantics.
  • Idempotency keys on every event so replays do not corrupt state.

For outbound delivery to your customer endpoints, always verify the payload signature to prevent spoofing. Here is how you verify a normalized webhook in Node.js:

const crypto = require('crypto');
 
function verifyWebhookSignature(req, signingSecret) {
  const signatureHeader = req.headers['x-truto-signature'];
  if (!signatureHeader) return false;
 
  const [timestampPart, hashPart] = signatureHeader.split(',');
  const timestamp = timestampPart.split('=')[1];
  const signature = hashPart.split('=')[1];
 
  // Prevent replay attacks (e.g., 5 minute tolerance)
  const fiveMinutesAgo = Date.now() - (5 * 60 * 1000);
  if (parseInt(timestamp) < fiveMinutesAgo) return false;
 
  const payloadToSign = `${timestamp}.${JSON.stringify(req.body)}`;
  
  const expectedSignature = crypto
    .createHmac('sha256', signingSecret)
    .update(payloadToSign)
    .digest('hex');
 
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

If you are deciding whether to build this internally, the designing reliable webhooks writeup covers the failure modes you will hit in month three.

Phase 4: The Zero-Downtime Cutover Strategy

You have audited the Make.com workflows, mapped the data using JSONata, and built the native authentication flow. Now you must migrate your active users without dropping data or forcing them to re-authenticate.

The operational risk in a Make migration is forcing every customer to re-authenticate, or worse, dropping data during the switch. A clean cutover takes four steps.

Step 1: The Dual-Write and Shadow Phase

Do not hard-cut your infrastructure. Stand up the native integration in production but route only telemetry, not user-visible writes. Run the new native integration in "shadow mode" alongside the Make.com scenarios.

  1. Configure your application to accept inbound data from both Make.com and your new unified API layer.
  2. Tag incoming records with their source (source: make vs source: native).
  3. Compare the unified API's output against the existing Make scenario output for the same tenant over a 1-2 week window. Diff at the field level. Ensure the JSONata transformations exactly match the business logic previously handled by the visual workflow builder. Fix mapping bugs before any customer sees them.

Step 2: The OAuth Token Migration (Hot-Swap)

If you previously forced customers to use your own custom OAuth app inside Make.com, you own the client credentials. You can programmatically extract the refresh tokens from your Make.com environment and inject them into your new integration infrastructure without prompting the user. Owning your OAuth apps is the only way to avoid vendor lock-in and prevent the dreaded "re-authentication cliff."

If the customer authenticated using Make.com's generic public OAuth clients, you cannot migrate the tokens. You must build a highly targeted in-app campaign prompting users to "Upgrade to our new native integration" via your white-labeled Link UI. Schedule it inside an existing product flow (a settings page banner, an onboarding step) rather than a cold email.

Step 3: Per-Tenant Feature Flag

Migrate one tenant at a time behind a flag. Start with internal accounts, then design partners, then friendly customers. Keep both pipelines running in parallel for that tenant for 48-72 hours.

  1. Activate Native Webhooks: Enable the inbound webhooks on your native integration layer.
  2. Monitor Error Rates: Watch your application logs for HTTP 429s and ensure your exponential backoff queues are handling the load gracefully using the normalized ratelimit-reset headers.

Step 4: The Read Cutover and Deprecation

Once you verify data parity and the cohort is stable, execute the final cutover:

  1. Pause the Make.com Scenarios: Turn off the active triggers in Make.com for a specific cohort of users.
  2. Decommission in Waves: Disable Make scenarios in groups, monitor your unified webhook stream for the same event volume, and only delete after a full billing cycle of clean operation to stop accumulating operation costs. Keep the scenarios disabled-but-present for 30 days in case of rollback.
Info

Measure success by tenant-level event parity, not by aggregate metrics. A 99% match rate sounds great until you realize the 1% gap is concentrated in your top three accounts.

Executing the Transition

Migrating away from Make.com is a necessary rite of passage for B2B SaaS companies moving upmarket. The honest assessment: migrating from Make.com prototypes to native integrations is mostly a discipline problem, not a technology problem.

The technology—declarative connectors, unified data models, normalized webhooks, owned OAuth—is well understood. Visual workflow builders are fantastic for internal prototyping, but they are fundamentally incapable of delivering the white-labeled, multi-tenant, zero-downtime integration experiences that enterprise buyers demand.

By replacing brittle point-to-point logic with declarative JSONata mappings, normalizing webhook ingestion, and taking strict control over your API rate limit queues, you transform integrations from an unpredictable operational expense into a core competitive advantage. You stop losing deals to competitors with native settings pages, and you stop punishing your own profit margins every time a customer scales their data volume.

The discipline part is refusing to ship one more Make scenario as a customer-facing feature once you have decided to migrate. The architecture is clear. The operational runbook is defined. It is time to execute.

FAQ

When should I migrate off Make.com for customer-facing integrations?
When more than 20% of your customers depend on Make scenarios you maintain, when enterprise deals stall on security review because of the third-party hop, or when per-operation credit costs start eating margin. If any of those are true, the migration ROI is already positive.
Can I migrate integrations without forcing users to re-authenticate?
Yes, but only if you own the underlying OAuth application credentials. If you do, you can programmatically extract and migrate the refresh tokens to your native infrastructure. If your Make scenarios used Make-owned OAuth apps, a one-time re-auth is unavoidable.
What replaces Make.com routers and filters in a native integration?
Business logic—branching, formatting, conditional routing—should live in your application code, not in the integration layer. The integration layer should only handle auth, transport, field mapping, and webhook normalization.
How do native unified APIs handle API rate limits differently than Make.com?
Make abstracts retries behind the visual builder, which hides scaling problems. A declarative unified API like Truto normalizes upstream rate limit info into standardized headers (like ratelimit-reset) but passes HTTP 429 errors directly to the caller, allowing your engineering team to natively control retry and backoff logic.
Is a unified API the same as an embedded iPaaS?
No. A unified API normalizes data models across providers in one category (e.g., all CRMs share a contact model). An embedded iPaaS is a workflow runtime you embed in your product. Most B2B SaaS use cases are better served by a unified API for the data layer.

More from our Blog