<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sapnesh Naik</title>
    <description>The latest articles on DEV Community by Sapnesh Naik (@sapnesh_naik_ngo).</description>
    <link>https://dev.to/sapnesh_naik_ngo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3884423%2Fc3bfbfef-0232-466f-a751-248f0e01963d.jpg</url>
      <title>DEV Community: Sapnesh Naik</title>
      <link>https://dev.to/sapnesh_naik_ngo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sapnesh_naik_ngo"/>
    <language>en</language>
    <item>
      <title>Build a GitHub API integration for AI agents using Nango</title>
      <dc:creator>Sapnesh Naik</dc:creator>
      <pubDate>Wed, 17 Jun 2026 18:01:20 +0000</pubDate>
      <link>https://dev.to/nangohq/build-a-github-api-integration-for-ai-agents-using-nango-1ei</link>
      <guid>https://dev.to/nangohq/build-a-github-api-integration-for-ai-agents-using-nango-1ei</guid>
      <description>&lt;p&gt;This guide shows how to build a custom, customer-facing GitHub API integration that the AI agents in your product can act on, using &lt;a href="https://nango.dev" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; and an AI coding agent (Codex, Claude Code, Cursor, or any other).&lt;/p&gt;

&lt;p&gt;By the end of this guide, you will have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ability for an AI agent in your product to create issues, comment on pull requests, and open PRs on a customer’s repositories, exposed as typed &lt;a href="https://nango.dev/docs/guides/functions/tool-calling" rel="noopener noreferrer"&gt;MCP tool calls&lt;/a&gt; instead of raw GitHub API parameters.&lt;/li&gt;
&lt;li&gt;A GitHub &lt;a href="https://nango.dev/docs/guides/auth/auth-guide" rel="noopener noreferrer"&gt;auth UI&lt;/a&gt; in your product (Nango Connect) so your customers can connect their own GitHub account or install your GitHub App.&lt;/li&gt;
&lt;li&gt;A durable sync that imports issues and pull requests from a customer’s repositories and keeps them up to date, so the agent always reasons over current data.&lt;/li&gt;
&lt;li&gt;A signature-verified webhook handler that reacts to GitHub events (pushes, pull requests, issues) in real time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hfx9s58epsupa3bllyr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hfx9s58epsupa3bllyr.gif" alt="Building a customer-facing GitHub API integration with Nango and an AI coding agent" width="600" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Get the working example:&lt;/strong&gt; the complete demo (frontend, backend, nango-integrations) is on GitHub at &lt;a href="https://github.com/NangoHQ/github-api-integration" rel="noopener noreferrer"&gt;NangoHQ/github-api-integration&lt;/a&gt;. Clone it to run the whole thing end to end, or follow the guide below and let Codex generate the same functions in your own project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is a GitHub API integration?
&lt;/h2&gt;

&lt;p&gt;A GitHub API integration connects your application or agent to a customer’s GitHub data (repositories, issues, pull requests, and commits) through GitHub’s REST and GraphQL APIs. It authenticates as a GitHub App or an OAuth App, reads data into your app with scheduled syncs, writes back with actions like creating issues or commenting on pull requests, and reacts to repository events through webhooks.&lt;/p&gt;

&lt;p&gt;Example use cases: an AI agent that triages a customer’s issues and opens pull requests, an AI code-review product that comments on PRs, a project management tool that mirrors a customer’s issues, or a developer analytics dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is it hard to integrate the GitHub API into your app?
&lt;/h2&gt;

&lt;p&gt;The GitHub REST API exposes repositories, issues, pull requests, commits, and webhooks. A production integration on top of it takes a few decisions up front, plus the infrastructure to keep them running.&lt;/p&gt;

&lt;p&gt;The first is the auth type. For a customer-facing product, a GitHub App is usually the right call; reach for an OAuth App only when you are building a personal-developer tool that should act purely as the user.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;GitHub App&lt;/th&gt;
&lt;th&gt;OAuth App&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Acts as&lt;/td&gt;
&lt;td&gt;A bot/installation&lt;/td&gt;
&lt;td&gt;The authorizing user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fine-grained permissions&lt;/td&gt;
&lt;td&gt;Yes, per resource&lt;/td&gt;
&lt;td&gt;No, inherits the user's scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate limit&lt;/td&gt;
&lt;td&gt;5,000 to 12,500/hour (scales with org)&lt;/td&gt;
&lt;td&gt;5,000/hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repository access&lt;/td&gt;
&lt;td&gt;Only repos granted at install&lt;/td&gt;
&lt;td&gt;Every repo the user can access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Customer-facing products&lt;/td&gt;
&lt;td&gt;Personal-developer tools&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href="https://nango.dev/blog/github-app-vs-github-oauth" rel="noopener noreferrer"&gt;GitHub App vs. GitHub OAuth&lt;/a&gt; and GitHub’s own &lt;a href="https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps" rel="noopener noreferrer"&gt;comparison&lt;/a&gt; for the full breakdown. The rest of the work is infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The auth flow is not standard OAuth, and tokens are short-lived:&lt;/strong&gt; GitHub App installation tokens expire after one hour. When “Expire user authorization tokens” is enabled (the default), user access tokens &lt;a href="https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/refreshing-user-access-tokens" rel="noopener noreferrer"&gt;expire after 8 hours and refresh tokens after 6 months&lt;/a&gt;. A failed refresh shows up as the &lt;a href="https://nango.dev/blog/github-app-oauth-refresh-token-bad-refresh-token" rel="noopener noreferrer"&gt;&lt;code&gt;BAD_REFRESH_TOKEN&lt;/code&gt;&lt;/a&gt; error, usually after a rotated client secret or a revoked installation. Someone has to store, refresh, and encrypt all of this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Issues API also returns pull requests:&lt;/strong&gt; &lt;code&gt;GET /repos/{owner}/{repo}/issues&lt;/code&gt; returns both issues and PRs, and every pull request carries a &lt;a href="https://docs.github.com/en/rest/issues/issues" rel="noopener noreferrer"&gt;&lt;code&gt;pull_request&lt;/code&gt;&lt;/a&gt; field. Filter on it or you double-count.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhooks need signature verification:&lt;/strong&gt; GitHub signs each delivery with the &lt;a href="https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries" rel="noopener noreferrer"&gt;&lt;code&gt;X-Hub-Signature-256&lt;/code&gt;&lt;/a&gt; header (an HMAC-SHA256 of the raw body using your webhook secret). You verify it with a constant-time comparison before trusting the payload, and read the event type from &lt;code&gt;X-GitHub-Event&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pagination is header-driven:&lt;/strong&gt; REST responses page through the &lt;code&gt;Link&lt;/code&gt; header (&lt;code&gt;rel="next"&lt;/code&gt;, up to 100 items per page), and some data is only practical through GitHub’s GraphQL API, which has its own point budget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Building all of this by hand takes weeks. With Nango and a coding agent like Codex, the same GitHub API integration ships in about an hour, the same workflow we used to &lt;a href="https://nango.dev/blog/learned-building-200-api-integrations-with-opencode" rel="noopener noreferrer"&gt;build 200+ integrations across five APIs in 15 minutes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Nango for a GitHub API integration
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nango.dev/" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; is the integration platform where coding agents build API integrations. An agent like Codex writes the integration as code in your repo, and Nango’s runtime runs it with managed auth, retries, and observability across &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;800+ APIs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For a GitHub integration, we will use these Nango features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Managed auth for GitHub Apps and OAuth:&lt;/strong&gt; your product gets a customizable, white-label &lt;a href="https://nango.dev/docs/guides/auth/auth-guide" rel="noopener noreferrer"&gt;auth UI&lt;/a&gt; where customers install your &lt;a href="https://nango.dev/docs/api-integrations/github-app" rel="noopener noreferrer"&gt;GitHub App&lt;/a&gt; or authorize a &lt;a href="https://nango.dev/docs/api-integrations/github" rel="noopener noreferrer"&gt;GitHub OAuth&lt;/a&gt; app, while Nango handles installation and user tokens, refresh, encryption, and revocation behind it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A function builder skill for Codex:&lt;/strong&gt; to build your integration logic, Codex uses the Nango &lt;a href="https://nango.dev/docs/guides/functions/functions-guide#option-2-build-locally-with-the-cli" rel="noopener noreferrer"&gt;function builder skill&lt;/a&gt;. It researches the GitHub API, writes your actions and syncs from a prompt, tests them against a real GitHub connection, and iterates on real errors until its tests pass against your connection. The same skill works with Claude Code, Cursor, Gemini CLI, and other agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrations infrastructure for every use case:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nango.dev/docs/guides/functions/action-functions" rel="noopener noreferrer"&gt;Actions&lt;/a&gt;: one-off operations like creating an issue, commenting on a PR, or opening a pull request.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nango.dev/docs/guides/functions/syncs/sync-functions" rel="noopener noreferrer"&gt;Syncs&lt;/a&gt;: scheduled functions that keep issues, PRs, and commits flowing into your app.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nango.dev/docs/getting-started/use-cases/webhooks-from-external-apis" rel="noopener noreferrer"&gt;Webhooks&lt;/a&gt;: receive GitHub events, verified, and route them to your integration in real time.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nango.dev/docs/guides/functions/tool-calling" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;: exposes your deployed actions as typed tools for the AI agents in your product.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nango.dev" rel="noopener noreferrer"&gt;Sign up for Nango&lt;/a&gt; (the free tier is enough for development).&lt;/li&gt;
&lt;li&gt;Add GitHub as an integration. Nango supports all the various GitHub auth types. In this demo, we’ll be registering a new &lt;a href="https://nango.dev/docs/api-integrations/github/how-to-set-up-a-github-app-with-nango" rel="noopener noreferrer"&gt;GitHub App&lt;/a&gt; (the “GitHub App OAuth” type, integration ID &lt;code&gt;github-app-oauth&lt;/code&gt;) with Nango’s callback URL &lt;code&gt;https://api.nango.dev/oauth/callback&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xlhtxbor4mpn7q72624.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xlhtxbor4mpn7q72624.png" alt="Configuring a GitHub App OAuth integration in the Nango dashboard with App ID, client ID, client secret, and private key" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a test connection: on the Nango dashboard, open the integration and select Connections &amp;gt; Add Test Connection, then authorize a GitHub account that owns a repository with a few issues and pull requests. While Codex builds your integration, it runs the generated code against this connection, so what ships has already worked against real data.&lt;/li&gt;
&lt;li&gt;Give Codex a project to build in. Install the &lt;a href="https://nango.dev/docs/reference/functions/functions-cli" rel="noopener noreferrer"&gt;Nango CLI&lt;/a&gt; and run &lt;code&gt;nango init&lt;/code&gt;: it creates a &lt;code&gt;nango-integrations&lt;/code&gt; folder with the Nango framework bootstrapped. Set &lt;code&gt;NANGO_SECRET_KEY_DEV&lt;/code&gt; (your dev API key, from Environment Settings in the dashboard) in &lt;code&gt;nango-integrations/.env&lt;/code&gt; so it can test and deploy on your behalf.&lt;/li&gt;
&lt;li&gt;Install the Nango skill. Run &lt;code&gt;npx skills add NangoHQ/skills -s building-nango-functions-locally&lt;/code&gt;; the installer detects Codex and copies the skill to &lt;code&gt;.agents/skills/&lt;/code&gt;, where &lt;a href="https://developers.openai.com/codex/skills" rel="noopener noreferrer"&gt;Codex discovers it&lt;/a&gt;. The same skill works with Claude Code, Cursor, and &lt;a href="https://nango.dev/docs/getting-started/coding-agent-setup" rel="noopener noreferrer"&gt;other coding agents&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; LLM training data on Nango is often stale. Add the Nango docs MCP server alongside the skill so Codex pulls current API references while it generates code: &lt;code&gt;codex mcp add nango-docs --url "https://nango.dev/docs/mcp"&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sync a customer’s issues and pull requests into your app
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://nango.dev/docs/guides/functions/syncs/sync-functions" rel="noopener noreferrer"&gt;sync&lt;/a&gt; keeps a fresh copy of a customer’s GitHub data in your app. Here it imports the issues and pull requests from a connected repository, then refreshes on a schedule so new activity shows up without anyone clicking refresh.&lt;/p&gt;

&lt;p&gt;You build it by prompting Codex with the Nango skill (type &lt;code&gt;$&lt;/code&gt; to mention a skill, or run &lt;code&gt;/skills&lt;/code&gt; to browse):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$building-nango-functions-locally Build a Nango sync for the github-app-oauth integration that imports
the issues and pull requests from the repos a customer connects and keeps them up to date,
refreshing every hour. Integrate it with my frontend.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b24stgxsp87f3lym8dr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b24stgxsp87f3lym8dr.gif" alt="Codex generating a Nango sync for GitHub issues and pull requests with the function builder skill" width="720" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the skill loaded, Codex:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Researches the GitHub API and the endpoints it needs.&lt;/li&gt;
&lt;li&gt;Writes the sync and a typed model for your records.&lt;/li&gt;
&lt;li&gt;Tests it against your real connection with &lt;code&gt;nango dryrun&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Iterates on any errors until the sync works end to end.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Codex generates this sync. You do not write it by hand.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;createSync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Imports issues and pull requests from a connected repo and refreshes hourly.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;every hour&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;autoStart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// starts once your app saves the repo metadata&lt;/span&gt;
    &lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GithubIssue&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMetadata&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;issues&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/repos/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/issues`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;updated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;per_page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;}))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// GET /issues returns pull requests too; the pull_request field tells them apart.&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;batchSave&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toRecord&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GithubIssue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;nango.paginate&lt;/code&gt; follows GitHub’s &lt;code&gt;Link&lt;/code&gt; header for you, so you do not hand-roll pagination. The full sync, with the record model, incremental updates keyed on issue activity, and the &lt;code&gt;onWebhook&lt;/code&gt; handler, is in &lt;a href="https://github.com/NangoHQ/github-api-integration/blob/main/nango-integrations/github-app-oauth/syncs/fetch-issues-and-pull-requests.ts" rel="noopener noreferrer"&gt;&lt;code&gt;fetch-issues-and-pull-requests.ts&lt;/code&gt;&lt;/a&gt; in the demo repo.&lt;/p&gt;

&lt;p&gt;When Codex finishes, it deploys the sync for you (approve the deploy when it asks):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nango deploy &lt;span class="nt"&gt;--sync&lt;/span&gt; fetch-issues-and-pull-requests dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the prompt said to integrate the frontend, Codex also wires &lt;a href="https://nango.dev/docs/guides/auth/auth-guide" rel="noopener noreferrer"&gt;Nango Connect&lt;/a&gt; into your app: customers install your GitHub App, pick which repositories to grant, and the sync starts on its own.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95xq584rvo3n5sqz6igw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95xq584rvo3n5sqz6igw.gif" alt="A customer connecting GitHub through Nango Connect and the sync importing their issues into the app" width="720" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your backend reads the synced records from Nango’s cache and serves them to your UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;records&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listRecords&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;providerConfigKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;github-app-oauth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;connectionId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GithubIssue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run the issues sync on demand
&lt;/h3&gt;

&lt;p&gt;Syncs run on a schedule (every hour in this example). When a customer wants fresh data immediately, give them a refresh button that triggers the sync on demand (behind the scenes, a &lt;code&gt;nango.triggerSync&lt;/code&gt; call) instead of waiting for the next run. The refresh endpoint that triggers the sync is in &lt;a href="https://github.com/NangoHQ/github-api-integration/blob/main/backend/server.mjs" rel="noopener noreferrer"&gt;&lt;code&gt;backend/server.mjs&lt;/code&gt;&lt;/a&gt; in the demo repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create issues and comment on pull requests from your app
&lt;/h2&gt;

&lt;p&gt;An &lt;a href="https://nango.dev/docs/guides/functions/action-functions" rel="noopener noreferrer"&gt;action&lt;/a&gt; is a one-off operation your product or an agent triggers on demand. This is the write-back direction: an AI agent files an issue from a support ticket, posts a review summary on a pull request, or opens a fix PR. Prompt Codex to build it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$building-nango-functions-locally Add an action to the github-app-oauth integration that creates an issue
in a customer's repo from a typed title, body, and labels.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpb9vs6x1mvbzm9q0q8ha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpb9vs6x1mvbzm9q0q8ha.png" alt="Codex in the IDE building and verifying the create-issue action for the GitHub integration" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Codex writes the action, tests it by opening a real issue in your connected test repository, and deploys it when you approve. The full action is in &lt;a href="https://github.com/NangoHQ/github-api-integration/blob/main/nango-integrations/github-app-oauth/actions/create-issue.ts" rel="noopener noreferrer"&gt;&lt;code&gt;create-issue.ts&lt;/code&gt;&lt;/a&gt; in the demo repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Codex generates this action; approve the deploy when it asks.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;createAction&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Create an issue in the connected repo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// creating an issue is not idempotent; a blind retry could open a duplicate&lt;/span&gt;
    &lt;span class="na"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/repos/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/issues`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;labels&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html_url&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On &lt;code&gt;retries: 0&lt;/code&gt;: creating an issue is not idempotent, so re-running the whole action after an unknown failure could open the same issue twice. Rate-limited requests are safe because they wrote nothing, and Nango’s proxy retries those for you.&lt;/p&gt;

&lt;p&gt;Deploy it the same way (Approve when Codex asks to deploy):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nango deploy &lt;span class="nt"&gt;--action&lt;/span&gt; create-issue dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zige0392ts40kjth8gx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zige0392ts40kjth8gx.png" alt="Deployed GitHub actions in the Nango dashboard: create-issue, create-comment, create-pull-request, and more, with enable toggles" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commenting on a pull request uses the same shape. In GitHub, a pull request is also an issue, so a comment posts to &lt;code&gt;/repos/{owner}/{repo}/issues/{number}/comments&lt;/code&gt; whether the number points at an issue or a PR. One more prompt adds an &lt;code&gt;add-issue-comment&lt;/code&gt; action, and a third opens a pull request from a branch with &lt;code&gt;POST /repos/{owner}/{repo}/pulls&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$building-nango-functions-locally Add actions to the github-app-oauth integration to comment on an issue
or PR, and to open a pull request from a head branch into a base branch.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can test any action from your app, or run it from the Nango dashboard with the &lt;a href="https://nango.dev/docs/updates/changelog#playground" rel="noopener noreferrer"&gt;Playground&lt;/a&gt; against your connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  React to GitHub events in real time with webhooks
&lt;/h2&gt;

&lt;p&gt;A scheduled sync is enough for most data, but GitHub is event-rich, and a lot of products need to react the moment a pull request opens or an issue changes. GitHub Apps deliver one &lt;a href="https://nango.dev/docs/getting-started/use-cases/webhooks-from-external-apis" rel="noopener noreferrer"&gt;webhook&lt;/a&gt; stream for the events you subscribe to (push, pull_request, issues, and more).&lt;/p&gt;

&lt;p&gt;Nango receives those webhooks, verifies the &lt;code&gt;X-Hub-Signature-256&lt;/code&gt; signature against your webhook secret, and forwards the verified event to your integration, so you do not write HMAC code. Prompt Codex to wire it up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$building-nango-functions-locally Subscribe the github-app-oauth integration to pull_request and issues
webhook events and update the synced records as soon as events arrive.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvur7fu7soa86fxfqqehl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvur7fu7soa86fxfqqehl.gif" alt="Codex subscribing the GitHub integration to pull_request and issues webhook events" width="720" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep the hourly sync running as a backstop. Webhook deliveries can be missed (a transient outage, a paused delivery), and a scheduled re-sync catches anything the event stream dropped. The combination of verified webhooks for freshness and a periodic sync for completeness is the pattern most production GitHub integrations settle on.&lt;/p&gt;

&lt;p&gt;One manual step is needed to start receiving events: point your GitHub App at Nango’s webhook URL. Copy it from your integration’s settings page in the Nango dashboard, then paste it into your GitHub App under Developer settings &amp;gt; GitHub Apps &amp;gt; your app &amp;gt; Webhook URL.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69x9ww2ynkadxh6xzmt2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69x9ww2ynkadxh6xzmt2.png" alt="Copying the webhook URL from the Nango integration settings into the GitHub App's webhook configuration" width="799" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Give AI agents in your product access to GitHub
&lt;/h2&gt;

&lt;p&gt;This is where the previous steps pay off: the sync gives the agent current GitHub data to reason over, and the actions become the tools it acts with. Once they are deployed, the AI agents inside your product can use them. Nango exposes enabled actions as typed tool calls through a hosted &lt;a href="https://nango.dev/docs/guides/functions/tool-calling" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;, so an agent calls &lt;code&gt;create-issue&lt;/code&gt; or &lt;code&gt;add-issue-comment&lt;/code&gt; with typed inputs instead of guessing raw GitHub API parameters.&lt;/p&gt;

&lt;p&gt;Point your MCP client at Nango’s server (Streamable HTTP transport) and pass three values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization:        Bearer &amp;lt;YOUR-NANGO-SECRET-KEY&amp;gt;
provider-config-key:  github-app-oauth
connection-id:        &amp;lt;CONNECTION-ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authorization:&lt;/strong&gt; your Nango secret key, held by your backend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;provider-config-key:&lt;/strong&gt; your GitHub integration ID (&lt;code&gt;github-app-oauth&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;connection-id:&lt;/strong&gt; the connection for the current user. Fetch it per logged-in user rather than hardcoding it, so each user’s agent acts on their own repositories.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Codex can wire this into your product’s agent for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$building-nango-functions-locally Wire my product's AI agent to Nango's MCP server for the github-app-oauth
integration, passing the logged-in user's connection id, so it can read issues and open PRs. Add flexible actions to Nango to make the agent feature complete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2cx80cag9qwpegxfqwmr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2cx80cag9qwpegxfqwmr.png" alt="An AI agent in a product using Nango MCP tools to create issues, close issues, and add labels, reflected live on GitHub" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you do not have an agent interface in your product yet but want to try the tools, add Nango’s MCP server to Codex itself. &lt;code&gt;codex mcp add&lt;/code&gt; does not support custom headers, so add it to &lt;code&gt;~/.codex/config.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[mcp_servers.nango_github]&lt;/span&gt;
&lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://api.nango.dev/mcp"&lt;/span&gt;
&lt;span class="py"&gt;bearer_token_env_var&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"NANGO_SECRET_KEY"&lt;/span&gt;
&lt;span class="py"&gt;http_headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;"connection-id"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;CONNECTION-ID&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;"provider-config-key"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"github-app-oauth"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then ask Codex: “Open an issue titled ‘Flaky test in checkout’ in my connected repo using the nango github MCP.” For the patterns that make these tool calls reliable in production, see &lt;a href="https://nango.dev/blog/build-reliable-tool-calls-for-ai-agents-integrating-with-external-apis" rel="noopener noreferrer"&gt;build reliable tool calls for AI agents&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; you can view detailed action and sync logs on the Nango dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foorbbw1jyl97xlnbcbzs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foorbbw1jyl97xlnbcbzs.png" alt="The Nango dashboard logs showing successful action, sync, and webhook runs for the GitHub integration" width="799" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Common issues
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Cause and fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;401 Bad credentials&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The token expired or the installation was revoked. Nango refreshes installation tokens (1 hour) and user tokens (8 hours) for you; if the customer removed the installation, they reconnect from your app.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;BAD_REFRESH_TOKEN&lt;/code&gt; on a user token&lt;/td&gt;
&lt;td&gt;The client secret was rotated or the installation was revoked. The customer reconnects. See the full breakdown.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;403&lt;/code&gt; or &lt;code&gt;429&lt;/code&gt; with &lt;code&gt;retry-after&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;A primary or secondary rate limit (100 concurrent requests, 900 points per minute). Nango retries with backoff; spread bulk work and avoid firing parallel requests at one installation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Issue sync contains pull requests&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;GET /issues&lt;/code&gt; returns PRs too. Filter on the &lt;code&gt;pull_request&lt;/code&gt; field to keep them separate.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Webhook rejected or ignored&lt;/td&gt;
&lt;td&gt;The &lt;code&gt;X-Hub-Signature-256&lt;/code&gt; HMAC did not match. Confirm the webhook secret on your GitHub App matches the one in Nango; Nango verifies the signature for you.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;404&lt;/code&gt; on a repo the user can see&lt;/td&gt;
&lt;td&gt;The GitHub App installation was not granted that repository. The customer adds it under the installation's repository access settings.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Endpoint returns &lt;code&gt;Not Found&lt;/code&gt; only for a GitHub App&lt;/td&gt;
&lt;td&gt;Some endpoints work only with OAuth Apps. Check for the "Works with GitHub Apps" note on the endpoint in GitHub's docs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;listRecords&lt;/code&gt; is empty right after connecting&lt;/td&gt;
&lt;td&gt;The sync starts only after your app saves the repo metadata, and the first run is asynchronous. Read records once a run completes.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Should I use a GitHub App or an OAuth App for a customer-facing product?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use a GitHub App. It installs per organization or repository with fine-grained permissions and rate limits that scale from 5,000 to 12,500 requests per hour. An OAuth App acts as the authorizing user and suits personal-developer tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you handle GitHub API rate limits when syncing data?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub allows 5,000 to 12,500 requests per hour, plus secondary limits of 100 concurrent requests and 900 points per minute. Spread bulk work, avoid firing parallel requests at one installation, and retry on &lt;code&gt;403&lt;/code&gt; or &lt;code&gt;429&lt;/code&gt; using the &lt;code&gt;retry-after&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you verify GitHub webhooks?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub signs each delivery with an &lt;code&gt;X-Hub-Signature-256&lt;/code&gt; header, an HMAC-SHA256 of the raw request body using your webhook secret. Verify it with a constant-time comparison before trusting the payload, and read the event type from the &lt;code&gt;X-GitHub-Event&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long does it take to build a GitHub API integration?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By hand, a production integration with auth, syncs, webhooks, and rate-limit handling takes weeks. With Nango and a coding agent like Codex, the agent writes and tests the same integration against a real connection in about an hour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;A production-grade GitHub API integration for agents comes down to customer auth, incremental sync, writing safely, reacting in real time (signature-verified webhooks), and staying inside two rate-limit systems. Together they become the tools the AI agents in your product call to act on a customer’s GitHub.&lt;/p&gt;

&lt;p&gt;With the Nango skill, Codex writes that logic as code from a prompt and tests it against a real connection, while Nango’s runtime handles managed OAuth, durable syncs, webhook verification, retries, and observability. The same workflow covers any of Nango’s &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;800+ supported APIs&lt;/a&gt;, and it scales into &lt;a href="https://nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;just-in-time integrations&lt;/a&gt;: integrations built on demand by an agent instead of pre-built for every use case.&lt;/p&gt;

&lt;p&gt;Clone the &lt;a href="https://github.com/NangoHQ/github-api-integration" rel="noopener noreferrer"&gt;demo project on GitHub&lt;/a&gt; to run it end to end, or build your first integration from the &lt;a href="https://nango.dev/docs/getting-started/quickstart" rel="noopener noreferrer"&gt;quickstart&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/github-app-vs-github-oauth" rel="noopener noreferrer"&gt;GitHub App vs. GitHub OAuth: when to use which&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/how-to-build-a-google-sheets-api-integration-with-nango-and-codex" rel="noopener noreferrer"&gt;How to build a Google Sheets API integration with Nango and Codex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/how-to-build-a-gmail-api-integration-with-nango-and-claude" rel="noopener noreferrer"&gt;How to build a Gmail API integration with Nango and Claude&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/using-ai-coding-agents-for-building-api-integrations" rel="noopener noreferrer"&gt;Using AI coding agents for building API integrations in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/nango-api-integrations-builder-skill" rel="noopener noreferrer"&gt;Introducing the Nango API integrations builder skill&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>github</category>
      <category>agents</category>
      <category>integrations</category>
    </item>
    <item>
      <title>Best open-source API integration platforms for AI agents in 2026</title>
      <dc:creator>Sapnesh Naik</dc:creator>
      <pubDate>Mon, 15 Jun 2026 19:09:15 +0000</pubDate>
      <link>https://dev.to/nangohq/best-open-source-api-integration-platforms-for-ai-agents-in-2026-2707</link>
      <guid>https://dev.to/nangohq/best-open-source-api-integration-platforms-for-ai-agents-in-2026-2707</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;“Open source” is one of the most common requirements when engineers pick an API integration platform for their AI agents and SaaS products. It promises three things: no vendor lock-in, a credential store you can inspect, and integrations you can extend rather than wait on a vendor’s catalog.&lt;/p&gt;

&lt;p&gt;Most tools publish only an open-source SDK, while the runtime that stores your customers’ credentials and runs your integrations remains closed. Nango is the exception in this comparison.&lt;/p&gt;

&lt;p&gt;This post compares four platforms by which parts of each are actually open source, from the client SDK to the runtime that stores credentials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nango:&lt;/strong&gt; The integration platform where coding agents build API integrations and your product consumes them across 800+ APIs. The whole platform is open source under the Elastic License 2.0, and integrations are code you own in your repo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composio:&lt;/strong&gt; A large hosted catalog of agent tools. The SDK is MIT, but the runtime that stores credentials and runs tool calls is closed source, and a &lt;a href="https://material.security/resources/the-composio-breach-one-token-10242-doors" rel="noopener noreferrer"&gt;May 2026 security incident&lt;/a&gt; forced customers to rotate keys and have their users re-authorize.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arcade.dev:&lt;/strong&gt; An MCP runtime with per-user OAuth. The tool-building framework is MIT, but the engine that holds tokens and executes calls is a closed binary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Superglue:&lt;/strong&gt; An open-source tool that uses an LLM to generate integrations on the fly. Useful for one-off integrations, but there is no prebuilt connector catalog, no managed data syncs or webhooks, and per-customer auth sits behind a paid tier.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why open source matters for AI agent integrations
&lt;/h2&gt;

&lt;p&gt;An integration platform holds three sensitive things: the OAuth tokens and API keys for your customers’ accounts, the data those APIs return, and the code that runs against them. Open source decides how much of that you can see and control.&lt;/p&gt;

&lt;p&gt;For teams building AI agents, three properties matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You can inspect the code that holds credentials.&lt;/strong&gt; A security reviewer can read how tokens are stored, encrypted, and refreshed instead of trusting a marketing page. Where those credentials live matters too. When they sit in one closed vendor cloud, a breach of that single system exposes every customer at once.
Composio’s May 2026 security incident exposed around 10,242 customer credentials and forced every customer to rotate keys and have their users re-authorize. An open, self-hostable platform lets you keep credentials on infrastructure you control and audit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You avoid lock-in.&lt;/strong&gt; When integrations are code you own, you can move them, fork them, and keep running them. When they are entries in a vendor’s catalog, you migrate by rewriting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You can extend it.&lt;/strong&gt; A coding agent like Claude Code, Cursor, or Codex can read an open integration, change it, and ship a new one. A closed catalog only lets you consume what the vendor already built.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem is that “open source” has become a label applied to a client SDK. The repo with the stars is often a thin wrapper. The part that matters for an integration platform, the runtime that stores credentials and executes calls, runs on the vendor’s cloud and has no public source.&lt;/p&gt;

&lt;h2&gt;
  
  
  What counts as open source for an integration platform
&lt;/h2&gt;

&lt;p&gt;The test is whether you can read, run, and self-host the component that stores your customers’ credentials and executes your integrations. That is the runtime. An open SDK, CLI, or MCP wrapper does not make the platform open source. It is client tooling, not the core infrastructure.&lt;/p&gt;

&lt;p&gt;The word “open source” also spans a few license types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Permissive (MIT, Apache-2.0):&lt;/strong&gt; Use, modify, and redistribute with almost no restrictions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source-available (Elastic License 2.0, Functional Source License):&lt;/strong&gt; Read, self-host, modify, and embed the code in your product. These carry limits, usually that you cannot resell the software as a competing managed service, but for a team that wants to run and extend the platform they behave like open source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proprietary:&lt;/strong&gt; No public source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ltgjrovwo82e7lrs7sn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ltgjrovwo82e7lrs7sn.png" alt="What is actually open source: every platform ships an open SDK, but the runtime that stores credentials is open only for Nango and Superglue" width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What to look for in an open-source platform for AI agents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;An open, self-hostable runtime and credential store:&lt;/strong&gt; The source for the part that stores tokens and runs integrations should be public, and you should be able to run it yourself. Check the actual repo, not the SDK.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code-first integrations you own:&lt;/strong&gt; Integrations should be code in your repo, version controlled and reviewable, so you are not locked into a catalog you cannot inspect or change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coding agents can build on it:&lt;/strong&gt; A skill or harness that lets Claude Code, Cursor, or Codex research an API, write an integration, test it against a real connection, and deploy it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More than tool calls:&lt;/strong&gt; Data syncs to keep agent context fresh for RAG, webhook processing and triggers to react to events, and per-customer configuration for tenant-specific behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;White-label, per-customer auth:&lt;/strong&gt; Each of your customers connects their own account under your brand, with token refresh handled for you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability and compliance:&lt;/strong&gt; Full request and response logs that both humans and agents can read, plus the certifications that regulated buyers ask about.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The best open-source API integration platforms for AI agents
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Nango
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nango.dev" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; is the integration platform where coding agents build API integrations. Engineers or coding agents like Claude Code, Cursor, and Codex, write integrations as code in your repo using the &lt;a href="https://nango.dev/docs/getting-started/coding-agent-setup" rel="noopener noreferrer"&gt;Nango AI builder skill&lt;/a&gt;. Nango’s runtime executes them securely and at scale, covering auth, tool calls, data syncs, webhooks, and triggers across &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;800+ APIs&lt;/a&gt;. It is &lt;a href="https://github.com/NangoHQ/nango" rel="noopener noreferrer"&gt;open source&lt;/a&gt; under the Elastic License 2.0; you can self-host it, and hundreds of &lt;a href="https://nango.dev/customers" rel="noopener noreferrer"&gt;fast-growing AI companies&lt;/a&gt; use it as core infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxstj222ohi4oab4muqw9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxstj222ohi4oab4muqw9.gif" alt="Nango API integrations catalog with 800+ supported providers" width="760" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is open&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The whole platform source is public under the Elastic License 2.0: the auth layer, the credential store, the proxy, and the execution runtime. You can read it, fork it, &lt;a href="https://nango.dev/docs/guides/platform/self-hosting" rel="noopener noreferrer"&gt;self-host it&lt;/a&gt;, and embed it in your product. The integrations themselves are TypeScript functions that live in your own repo, so that code is yours. Nango also publishes a library of integration templates you can clone and customize as a starting point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbeda3pt43upjqfa7k1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbeda3pt43upjqfa7k1j.png" alt="How Nango works: your product and coding agents connect to external APIs through Nango" width="800" height="830"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams building AI agents or SaaS products that want an integration platform they can read, extend, and self-host, where coding agents build the integrations, and the AI agents and features in their product consume them across hundreds of APIs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The runtime and credential store are open source:&lt;/strong&gt; You can read how tokens are stored, encrypted, and refreshed, and audit them in a security review. In self-hosted deployments, tokens live in your own database and are encrypted at rest with your own key. This is the component that the other platforms here keep closed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open code and a sandboxed runtime, so security teams can sign off:&lt;/strong&gt; Because the platform is open source, your engineers and the wider community can review how credentials are handled instead of trusting a vendor’s cloud. The execution runtime isolates each run, so one customer’s integration cannot reach another’s. See &lt;a href="https://nango.dev/blog/how-nango-runs-untrusted-customer-code-at-scale" rel="noopener noreferrer"&gt;how Nango runs untrusted customer code at scale&lt;/a&gt; for the architecture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI builder skill for 18+ coding agents:&lt;/strong&gt; One command installs the skill. It gives Claude Code, Cursor, Codex, Gemini CLI, and others the context to research an API, write the integration, and test it against a real connection. See the walkthrough of &lt;a href="https://nango.dev/blog/how-to-build-a-real-time-google-calendar-api-integration" rel="noopener noreferrer"&gt;building a real-time Google Calendar integration&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install the Nango builder skill for your coding agent&lt;/span&gt;
npx skills add NangoHQ/skills &lt;span class="nt"&gt;-s&lt;/span&gt; building-nango-functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ZG597mH9ZDg"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test generated code against real APIs:&lt;/strong&gt; The Nango CLI ships a &lt;code&gt;nango dryrun&lt;/code&gt; command that runs generated code against a real connection and returns real responses, so the agent iterates on actual errors instead of hallucinating endpoints. The &lt;a href="https://nango.dev/docs/updates/changelog" rel="noopener noreferrer"&gt;remote function builder&lt;/a&gt; lets a coding agent compile, dry-run, and deploy an integration without a local project, straight from a prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code-first integrations you own, with no catalog lock-in:&lt;/strong&gt; Integrations are &lt;a href="https://nango.dev/docs/guides/functions/functions-guide" rel="noopener noreferrer"&gt;functions&lt;/a&gt; in your repo, deployed through CI/CD. A coding agent can fork a template, change a field, or add an API that Nango does not cover yet. You are never blocked waiting for a vendor to add a connector.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in MCP server and typed tool calls:&lt;/strong&gt; Every action is a deterministic &lt;a href="https://nango.dev/docs/guides/functions/tool-calling" rel="noopener noreferrer"&gt;tool call&lt;/a&gt; over both a REST API and a hosted MCP server, with strict input and output schemas so the model does not guess parameters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beyond tool calls on the same platform:&lt;/strong&gt; Durable incremental &lt;a href="https://nango.dev/docs/guides/functions/syncs/sync-functions" rel="noopener noreferrer"&gt;data syncs&lt;/a&gt; keep data fresh for RAG, &lt;a href="https://nango.dev/docs/getting-started/use-cases/webhooks-from-external-apis" rel="noopener noreferrer"&gt;webhook processing&lt;/a&gt; and polling triggers react to provider events, and &lt;a href="https://nango.dev/docs/getting-started/use-cases/customer-configuration" rel="noopener noreferrer"&gt;per-customer configuration&lt;/a&gt; adapts behavior per tenant without forking code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;White-label auth across 800+ APIs:&lt;/strong&gt; A drop-in &lt;a href="https://nango.dev/docs/guides/auth/customize-connect-ui" rel="noopener noreferrer"&gt;Connect UI&lt;/a&gt; handles OAuth, API keys, JWT, basic auth, and MCP Auth, with token refresh built in. Your end users authorize under your brand, not the platform’s.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9u89rt6u2jojrtvxmdhz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9u89rt6u2jojrtvxmdhz.gif" alt="Nango drop-in Connect UI for end-user authorization" width="720" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Observability built for agents:&lt;/strong&gt; Every operation produces &lt;a href="https://nango.dev/docs/guides/platform/observability" rel="noopener noreferrer"&gt;structured logs&lt;/a&gt; with full request and response details, exported through OpenTelemetry. A coding agent can read a failing run and ship a fix on its own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz3ewrpmwhbtgdg5n3w2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz3ewrpmwhbtgdg5n3w2.png" alt="Nango observability dashboard showing detailed API integration logs" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise compliance:&lt;/strong&gt; &lt;a href="https://trust.nango.dev" rel="noopener noreferrer"&gt;SOC 2 Type II, GDPR, and HIPAA&lt;/a&gt;, with a BAA available on request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free self-hosting covers auth and the proxy; the full runtime is a paid tier:&lt;/strong&gt; You can self-host the auth layer and the API proxy for free. Running the complete platform yourself, with functions, data syncs, webhooks, and the MCP server, needs &lt;a href="https://nango.dev/blog/best-self-hosted-api-integration-platforms-for-ai-agents" rel="noopener noreferrer"&gt;Enterprise self-hosting&lt;/a&gt;. Most teams use Nango Cloud, which the Nango team runs for you, so you ship integrations without provisioning and operating your own servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Composio
&lt;/h3&gt;

&lt;p&gt;Composio is a hosted tool-calling platform for AI agents. It provides agents with managed OAuth and a single MCP endpoint to access a large catalog of app toolkits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7y8q37y05dj8hpsf0gs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7y8q37y05dj8hpsf0gs.png" alt="Composio platform overview" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is open&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Python and TypeScript SDKs, the CLI, and the framework adapters are MIT-licensed. The part that matters is not. The backend that stores your customers’ OAuth tokens and executes tool calls is closed source and runs on Composio’s cloud. The prebuilt tools are closed too, so you cannot read or modify them. An open SDK sits on top of a proprietary platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that want a large hosted catalog of pre-built agent tools and are comfortable with a closed runtime where credentials live in the vendor’s cloud. A reasonable fit for internal productivity or personal automation agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large catalog:&lt;/strong&gt; Over 1,000 app toolkits, with a Tool Router that selects relevant tools to keep the agent’s context small.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIT-licensed SDKs with broad framework support:&lt;/strong&gt; Adapters for OpenAI, Anthropic, LangChain, CrewAI, and others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed per-user auth:&lt;/strong&gt; Connected accounts are scoped to your user IDs and automatically refresh tokens. SOC 2 Type II and ISO 27001 certified.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A closed cloud that concentrates credentials, with a track record:&lt;/strong&gt; In May 2026, a breach of Composio’s systems exposed around 10,242 customer credentials, including 5,001 GitHub OAuth tokens and roughly 5,241 API keys. Composio deleted all existing API keys and required every customer to rotate keys. Because it could not revoke connected-account tokens on its own, customers had to ask their end-users to re-authorize. An &lt;a href="https://material.security/resources/the-composio-breach-one-token-10242-doors" rel="noopener noreferrer"&gt;independent analysis&lt;/a&gt; traced the scale of the exposure to credentials being aggregated in a single closed cloud. The platform is closed source, so customers could not inspect what ran or verify the fix, and no detailed root-cause postmortem was published.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The runtime and credential store are closed:&lt;/strong&gt; On every tier except enterprise, your customers’ tokens sit in Composio’s cloud, and every call routes through its backend. You cannot inspect or self-host the part that matters most.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You cannot deploy your own connector:&lt;/strong&gt; Custom tools are limited, and there is no path for a coding agent to author a new integration and ship it to Composio’s runtime. You consume the catalog, you do not extend it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool calls only:&lt;/strong&gt; There is no managed data sync layer for RAG, and there is no first-class webhook ingestion. Event-driven and scheduled work lives elsewhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a deeper comparison, see the &lt;a href="https://nango.dev/blog/composio-vs-nango" rel="noopener noreferrer"&gt;Composio vs Nango head-to-head&lt;/a&gt; and the &lt;a href="https://nango.dev/blog/composio-alternatives" rel="noopener noreferrer"&gt;best Composio alternatives&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Arcade.dev
&lt;/h3&gt;

&lt;p&gt;Arcade is an MCP runtime for agent tool calling, built around per-user authorization. When a tool call lacks a user grant, the Arcade Engine runs the OAuth flow, stores the tokens, and injects them at call time, so credentials never enter the model context.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2nheesdmelebv7ivtoo9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2nheesdmelebv7ivtoo9.png" alt="Arcade platform overview" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is open&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;arcade-mcp&lt;/code&gt; framework for building tools is MIT-licensed. The engine is not. The component that stores credentials and runs your tool calls ships as a closed binary with no public source. As with Composio, the open part is the client tooling, not the infrastructure that holds your customers’ tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams building MCP-first agents that only need tool calls to APIs, and do not need webhooks, triggers, data syncs, or a coding-agent skill for building and shipping integrations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Per-user OAuth built for agents:&lt;/strong&gt; Authorization is checked before execution and tokens never enter the model context, which is a sound security model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIT framework for custom tools:&lt;/strong&gt; You can build and package custom MCP servers with an open framework, with skills for Claude Code and Cursor that scaffold new tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-ecosystem signals:&lt;/strong&gt; Arcade joined the Linux Foundation’s Agentic AI Foundation as a Gold Member in December 2025.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The engine is a closed binary:&lt;/strong&gt; The exact component that stores end-customer credentials and executes calls has no public source, so you cannot audit or fork it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool calls only:&lt;/strong&gt; No data syncs to feed agent context, no webhook ingestion, no scheduled triggers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Catalog-bound, not white-label embedded:&lt;/strong&gt; It is designed for an agent to consume a shared tool catalog, not for a SaaS to offer per-customer, white-label auth to its own end customers. The first-party catalog is roughly 112 integrations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full self-hosting is enterprise-only:&lt;/strong&gt; Running the binary yourself is free, but production on-premise deployment is gated to a sales contract, and the engine stays closed wherever it runs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Superglue
&lt;/h3&gt;

&lt;p&gt;Superglue takes a different approach. Instead of a fixed catalog, you describe an integration task in natural language and its LLM pipeline generates the integration code, runs it against the target API, and self-heals when the API drifts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fis1nshqolkds9a0iqqfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fis1nshqolkds9a0iqqfb.png" alt="Superglue dashboard" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is open&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Superglue is more open than Composio and Arcade. It publishes the runtime itself as open source, including the server, dashboard, and credential store, which you can run with &lt;code&gt;docker compose up&lt;/code&gt;. Tokens stay in your own database. Two things narrow it down for a product team. The license is the Functional Source License, which lets you self-host and modify the code but restricts its use for building a competing commercial product for two years after each release. The multi-tenant features of a customer-facing product, per-end-user credentials, role-based access, and a white-label portal are included in the paid Enterprise Edition, so the free core is effectively single-tenant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that want an LLM to generate one-off integrations against arbitrary REST, GraphQL, or SQL sources, and do not need a prebuilt connector catalog or per-customer auth in the free version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open-source runtime you can self-host for free:&lt;/strong&gt; Credentials stay in your own database, with your encryption key. You bring your own LLM provider key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coding-agent-first by design:&lt;/strong&gt; It ships a skill for Claude Code and Cursor and an MCP server, and the integration is generated rather than picked from a catalog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-healing integrations:&lt;/strong&gt; When an upstream response changes, the pipeline attempts to repair the integration automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The license restricts embedding it in a product:&lt;/strong&gt; The Functional Source License lets you self-host and modify the code, but you cannot use Superglue to build a competing commercial product until two years after each release. For a team embedding an integration platform in their own product, that is a real constraint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedded multi-tenancy is paid:&lt;/strong&gt; Per-customer credentials, role-based access, and white-label auth, the core of an embedded use case, sit in the Enterprise Edition, not the free core.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM-generated integrations need review:&lt;/strong&gt; Each integration is generated against the API you point it at, so correctness depends on the API’s docs and the self-heal loop. There is no library of tested, maintained connectors to fall back on, so you review and test the generated code before it goes to production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not a full integrations platform:&lt;/strong&gt; It generates and runs integrations, but it does not offer durable incremental data syncs at scale or first-class webhook ingestion in the free core, so it covers less ground than a platform like Nango.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Open source by component
&lt;/h2&gt;

&lt;p&gt;A GitHub repo alone does not tell you what is open. This table breaks each platform down by component: the runtime that stores credentials, the license, and the prebuilt connectors.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component or property&lt;/th&gt;
&lt;th&gt;Nango&lt;/th&gt;
&lt;th&gt;Composio&lt;/th&gt;
&lt;th&gt;Arcade.dev&lt;/th&gt;
&lt;th&gt;Superglue&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Runtime and credential store open source&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform license&lt;/td&gt;
&lt;td&gt;Elastic License 2.0&lt;/td&gt;
&lt;td&gt;Proprietary (MIT SDK only)&lt;/td&gt;
&lt;td&gt;Proprietary (MIT framework only)&lt;/td&gt;
&lt;td&gt;Functional Source License&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Who holds credentials (self-serve)&lt;/td&gt;
&lt;td&gt;You (self-host) or your Nango account&lt;/td&gt;
&lt;td&gt;Composio cloud&lt;/td&gt;
&lt;td&gt;Arcade cloud, or your backend if you run the binary&lt;/td&gt;
&lt;td&gt;You (your database)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-host the full runtime&lt;/td&gt;
&lt;td&gt;Free + Enterprise&lt;/td&gt;
&lt;td&gt;Enterprise only (closed images)&lt;/td&gt;
&lt;td&gt;Partial (free binary, on-prem is Enterprise)&lt;/td&gt;
&lt;td&gt;Free + Enterprise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrations you own as code&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No (catalog)&lt;/td&gt;
&lt;td&gt;Partial (tools via SDK)&lt;/td&gt;
&lt;td&gt;Yes (generated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding agents build integrations&lt;/td&gt;
&lt;td&gt;Yes (18+ agents, dry-run)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Partial (author tools, closed runtime)&lt;/td&gt;
&lt;td&gt;Yes (LLM-generated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data syncs and webhooks&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;White-label per-customer auth&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Enterprise only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prebuilt connectors&lt;/td&gt;
&lt;td&gt;800+ (open templates)&lt;/td&gt;
&lt;td&gt;1,000+ (closed)&lt;/td&gt;
&lt;td&gt;~112&lt;/td&gt;
&lt;td&gt;None (bring your own API)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Catalog counts use each vendor’s own unit (APIs, toolkits, integrations) and are not directly comparable.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to choose
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You want an open, self-hostable platform where coding agents build integrations and your product consumes them across hundreds of APIs:&lt;/strong&gt; pick Nango. It is the broadest option here, with an open-source runtime, code-first integrations you own, and data syncs and webhooks alongside tool calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want a large hosted catalog of agent tools and accept a closed runtime with credentials in the vendor cloud:&lt;/strong&gt; Composio fits, best for internal or personal automation agents. Weigh its May 2026 security incident and the closed-source risk before putting it on the path of production credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want per-user OAuth for MCP tool calling and tool calls are your whole scope:&lt;/strong&gt; Arcade.dev is worth a look, if a closed engine and no syncs or webhooks are acceptable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want an LLM to generate one-off integrations against arbitrary APIs:&lt;/strong&gt; Superglue is interesting. For a product that needs a connector catalog, managed syncs and webhooks, and per-customer auth, Nango is the broader fit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is the best open-source API integration platform for AI agents?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nango is the strongest open option for AI agents in 2026. Its runtime, connectors, and templates are open source under the Elastic License 2.0, so you can inspect, fork, self-host, and embed it. Integrations are code you own in your repo, and coding agents like Claude Code, Cursor, and Codex can build new ones directly against it, with data syncs and webhooks on the same platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Composio open source?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Composio’s Python and TypeScript SDKs are MIT-licensed, but the part that matters, the runtime that stores your customers’ credentials and executes tool calls, is closed source. The prebuilt tools cannot be inspected or modified, and a May 2026 security incident exposed credentials stored in that closed cloud.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Arcade.dev open source?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Arcade’s &lt;code&gt;arcade-mcp&lt;/code&gt; tool-building framework is MIT-licensed, but the Arcade Engine that stores credentials and runs tool calls is a closed binary with no public source. Full on-premise deployment is enterprise-only, and the engine stays closed wherever it runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Nango open source?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Nango is open source under the Elastic License 2.0. You can read the code, self-host it, modify it, and embed it in your product. You can audit how credentials are stored, run it on your own infrastructure, and extend any integration as code in your repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use n8n or Activepieces for customer-facing product integrations?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both are built for internal workflow automation, and their licenses reflect that. n8n’s Sustainable Use License limits use to internal business purposes, so embedding it in a customer-facing product needs a separate commercial license. Activepieces has an MIT core, but its embedding and white-label features sit in a paid enterprise edition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use these platforms with LangChain, CrewAI, or the OpenAI Agents SDK?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. All of them expose integrations through some combination of REST APIs, MCP servers, and SDKs that work with the popular agent frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Most platforms in this category publish an open-source SDK while the credential store and runtime stay on the vendor’s cloud. Composio and Arcade both keep the engine that holds your customers’ tokens closed, and Composio’s May 2026 breach showed what that concentration of credentials can cost. Superglue does publish its runtime, but its license restricts embedding it in a product, and its multi-tenant features and connector coverage push a product team toward the paid tier.&lt;/p&gt;

&lt;p&gt;Nango is the broadest open option of the four. The platform is open source under the Elastic License 2.0, integrations are code you own in your repo, and you can self-host it. Coding agents build the integrations, the AI agents in your product consume them through an MCP server, tool calls, data syncs, and webhooks, and the same code runs on a tenant-isolated runtime you can read and audit.&lt;/p&gt;

&lt;p&gt;If you want to try the Nango AI builder skill with your favorite coding agent, follow the &lt;a href="https://nango.dev/docs/guides/functions/functions-guide" rel="noopener noreferrer"&gt;Nango functions guide&lt;/a&gt; to get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/best-self-hosted-api-integration-platforms-for-ai-agents" rel="noopener noreferrer"&gt;Best self-hosted API integration platforms for AI agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/best-agentic-api-integrations-platform" rel="noopener noreferrer"&gt;Best agentic API integrations platform in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/best-api-integration-platforms-claude-code-cursor-codex" rel="noopener noreferrer"&gt;Best API integration platforms to use with Claude Code, Cursor, and Codex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/composio-alternatives" rel="noopener noreferrer"&gt;Best Composio alternatives for AI agent integrations in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/composio-vs-nango" rel="noopener noreferrer"&gt;Composio vs Nango: a developer’s comparison for production AI agent integrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/guide-to-secure-ai-agent-api-authentication" rel="noopener noreferrer"&gt;A guide to secure AI agent API authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;The emergence of just-in-time integrations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to build a Google Sheets API integration with Nango and Codex</title>
      <dc:creator>Sapnesh Naik</dc:creator>
      <pubDate>Fri, 12 Jun 2026 15:39:22 +0000</pubDate>
      <link>https://dev.to/nangohq/how-to-build-a-google-sheets-api-integration-with-nango-and-codex-449i</link>
      <guid>https://dev.to/nangohq/how-to-build-a-google-sheets-api-integration-with-nango-and-codex-449i</guid>
      <description>&lt;p&gt;This guide shows how to build a custom, customer-facing Google Sheets API integration with &lt;a href="https://nango.dev" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; and an AI coding agent (Codex, Claude Code, Cursor, or any other).&lt;/p&gt;

&lt;p&gt;By the end of this guide, you will have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Google Sheets &lt;a href="https://nango.dev/docs/guides/auth/auth-guide" rel="noopener noreferrer"&gt;auth UI&lt;/a&gt; in your product (Nango Connect) so your customers can connect their own spreadsheets to your app.&lt;/li&gt;
&lt;li&gt;A durable sync that imports rows from a connected spreadsheet and keeps them up to date as the sheet changes.&lt;/li&gt;
&lt;li&gt;The ability to append rows to a customer’s spreadsheet and export reports to new spreadsheets, from your UI or from an AI agent in your product (via an MCP tool call).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlqxx79uoxzlvoue8yd5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlqxx79uoxzlvoue8yd5.gif" alt="The YourApp demo: an in-app AI assistant adds and updates rows in a customer's connected Google Sheet while the sync keeps the app's table current" width="600" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Get the working example:&lt;/strong&gt; the complete demo (frontend, backend, nango-integrations) is on GitHub at &lt;a href="https://github.com/NangoHQ/google-sheets-api-integration" rel="noopener noreferrer"&gt;NangoHQ/google-sheets-api-integration&lt;/a&gt;. Clone it to run the whole thing end to end, or follow the guide below and let Codex generate the same functions in your own project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why is it hard to integrate the Google Sheets API into your app?
&lt;/h2&gt;

&lt;p&gt;A production Google Sheets API integration needs a few decisions up front:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You need an OAuth app, not an API key:&lt;/strong&gt; a Google Sheets API key only reads public spreadsheets. Accessing customer spreadsheets takes an OAuth 2.0 app with a consent screen, token refresh, and revocation handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decide on scopes early, they set your verification timeline:&lt;/strong&gt; most integrations request &lt;code&gt;https://www.googleapis.com/auth/spreadsheets&lt;/code&gt;, the standard read-write scope. Google classifies it as &lt;a href="https://developers.google.com/workspace/sheets/api/scopes" rel="noopener noreferrer"&gt;sensitive&lt;/a&gt;, so your app needs verification to go live (unverified apps cap at 100 users), and while the OAuth app’s publishing status is Testing, refresh tokens &lt;a href="https://developers.google.com/identity/protocols/oauth2#expiration" rel="noopener noreferrer"&gt;expire every 7 days&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan around the rate limits:&lt;/strong&gt; the quota is 300 read and 300 write requests per minute per project, and 60 per user. Past that, requests fail with &lt;code&gt;429: Too many requests&lt;/code&gt;, and Google’s &lt;a href="https://developers.google.com/workspace/sheets/api/limits" rel="noopener noreferrer"&gt;limits page&lt;/a&gt; says exceeding quota is planned to incur charges later in 2026.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Google Sheets webhooks:&lt;/strong&gt; the v4 API has no push notifications. Change detection means polling, or Drive API &lt;a href="https://developers.google.com/workspace/drive/api/guides/push" rel="noopener noreferrer"&gt;&lt;code&gt;files.watch&lt;/code&gt;&lt;/a&gt; channels that expire after at most one day and carry no payload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decide whether you want Google’s auto-formatting on writes:&lt;/strong&gt; &lt;a href="https://developers.google.com/workspace/sheets/api/reference/rest/v4/ValueInputOption" rel="noopener noreferrer"&gt;&lt;code&gt;valueInputOption=USER_ENTERED&lt;/code&gt;&lt;/a&gt; parses values the way the Sheets UI does (strings can become numbers and dates), while &lt;code&gt;RAW&lt;/code&gt; stores them as-is. Phone numbers and zip codes usually belong in &lt;code&gt;RAW&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep the data you write contiguous:&lt;/strong&gt; &lt;a href="https://developers.google.com/workspace/sheets/api/reference/rest/v4/spreadsheets.values/append" rel="noopener noreferrer"&gt;&lt;code&gt;values.append&lt;/code&gt;&lt;/a&gt; looks for a “table” in the target range and writes after the last one it finds, so empty rows shift where new rows land.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid hardcoding sheet names or ranges:&lt;/strong&gt; customers rename tabs and reorder columns, which breaks A1 ranges (&lt;code&gt;Unable to parse range&lt;/code&gt;). Store the stable numeric &lt;code&gt;sheetId&lt;/code&gt;, resolve the current tab name with &lt;code&gt;spreadsheets.get&lt;/code&gt; before building ranges, and read headers instead of assuming column order.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Building all of this by hand takes weeks. With Nango and a coding agent like Codex, the same Google Sheets API integration can ship in about an hour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Nango for a Google Sheets API integration
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nango.dev/" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; is the integration platform where coding agents build API integrations. An agent like Codex writes the integration as code in your repo, and Nango’s runtime runs it with managed auth, retries, and observability across &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;800+ APIs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For a Google Sheets integration, we will use these Nango features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OAuth for Google Sheets:&lt;/strong&gt; your product gets a customizable, white-label &lt;a href="https://nango.dev/docs/guides/auth/auth-guide" rel="noopener noreferrer"&gt;auth UI&lt;/a&gt; where customers connect their &lt;a href="https://nango.dev/docs/api-integrations/google-sheet" rel="noopener noreferrer"&gt;Google Sheets&lt;/a&gt; account, while Nango handles token storage, refresh, and encryption behind it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A function builder skill for Codex:&lt;/strong&gt; to build your integration logic and flows, Codex uses the Nango &lt;a href="https://nango.dev/docs/guides/functions/functions-guide" rel="noopener noreferrer"&gt;function builder skill&lt;/a&gt;. It researches the Sheets API, writes your actions and syncs from a prompt, tests them against a real Google Sheets connection, and iterates until the integration works end to end.
Note: The Nango skill also works with other coding agents like Claude Code, Cursor, Gemini CLI, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrations infrastructure for every use case:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nango.dev/docs/guides/functions/action-functions" rel="noopener noreferrer"&gt;Actions&lt;/a&gt;: one-off operations on a customer’s sheet, like appending a row or creating a spreadsheet.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nango.dev/docs/guides/functions/syncs/sync-functions" rel="noopener noreferrer"&gt;Syncs&lt;/a&gt;: scheduled functions that keep spreadsheet rows flowing into your app.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nango.dev/docs/getting-started/use-cases/webhooks-from-external-apis" rel="noopener noreferrer"&gt;Webhooks&lt;/a&gt;: route external events, like Drive file-change notifications, to your integration.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nango.dev/docs/guides/functions/tool-calling" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;: exposes your deployed actions as tools for the AI agents in your product.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nango also has pre-built actions and syncs for Google Sheets. They cover the common operations (a worksheet &lt;code&gt;rows&lt;/code&gt; sync, appending values, reading values, upserting rows, creating spreadsheets) and you can &lt;a href="https://nango.dev/blog/nango-clone-customize-integration-templates" rel="noopener noreferrer"&gt;enable them&lt;/a&gt; from your dashboard and use them right away, without building anything. Or have Codex clone and customize them to fit your use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nango.dev" rel="noopener noreferrer"&gt;Sign up for Nango&lt;/a&gt; (the free tier is enough for development).&lt;/li&gt;
&lt;li&gt;Add Google Sheets as an integration on the Nango dashboard. For this tutorial, use Nango’s pre-configured developer app: activate the shared credentials on the integration page and skip the Google Cloud setup entirely. For production, register your &lt;a href="https://nango.dev/docs/api-integrations/google-sheet/how-to-register-your-own-google-sheet-api-oauth-app" rel="noopener noreferrer"&gt;own Google OAuth app&lt;/a&gt; with Nango’s callback URL &lt;code&gt;https://api.nango.dev/oauth/callback&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6hcjo3mki58s1r4jngk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6hcjo3mki58s1r4jngk.png" alt="Configuring the google-sheet integration in the Nango dashboard: Nango's developer app credentials with the spreadsheets scope" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a test connection: on the Nango dashboard, open the integration and select Connections &amp;gt; Add Test Connection, then authorize a Google account that owns a spreadsheet with a few rows of data (your own or any test account). While Codex builds your integration, it runs the generated code against this connection, so what ships has already worked against real data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcyx20ccmz27a8n6gogl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcyx20ccmz27a8n6gogl.gif" alt="Adding a Google Sheets test connection in the Nango dashboard and authorizing a Google account" width="600" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give Codex a project to build in. Install the &lt;a href="https://nango.dev/docs/reference/functions/functions-cli" rel="noopener noreferrer"&gt;Nango CLI&lt;/a&gt; and run &lt;code&gt;nango init&lt;/code&gt;: it creates a &lt;code&gt;nango-integrations&lt;/code&gt; folder with the Nango framework bootstrapped, and Codex writes and deploys your syncs and actions from there. Set &lt;code&gt;NANGO_SECRET_KEY_DEV&lt;/code&gt; (your dev API key, from Environment Settings in the dashboard) in &lt;code&gt;nango-integrations/.env&lt;/code&gt; so it can test and deploy on your behalf.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8ut9rfhrptk5xlell94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8ut9rfhrptk5xlell94.png" alt="Running nango init in the terminal to bootstrap the nango-integrations project" width="800" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the Nango skill. Run &lt;code&gt;npx skills add NangoHQ/skills -s building-nango-functions-locally&lt;/code&gt;; the installer detects Codex and copies the skill to &lt;code&gt;.agents/skills/&lt;/code&gt;, where &lt;a href="https://developers.openai.com/codex/skills" rel="noopener noreferrer"&gt;Codex discovers it&lt;/a&gt;. The same skill works with Claude Code, Cursor, and &lt;a href="https://nango.dev/docs/getting-started/coding-agent-setup" rel="noopener noreferrer"&gt;other coding agents&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzu75mfl0segy2wbfyhbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzu75mfl0segy2wbfyhbg.png" alt="Installing the building-nango-functions-locally skill for Codex with npx skills add" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; LLM training data on Nango is often stale. Add the Nango docs MCP server alongside the skill so Codex pulls current API references while it generates code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex mcp add nango-docs &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s2"&gt;"https://nango.dev/docs/mcp"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sync customer spreadsheet rows to your app
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://nango.dev/docs/guides/functions/syncs/sync-functions" rel="noopener noreferrer"&gt;sync&lt;/a&gt; keeps a fresh copy of the customer’s sheet in your app. Here it imports every row of the spreadsheet they connect, then refreshes on a schedule so edits show up without anyone clicking refresh.&lt;/p&gt;

&lt;p&gt;You build it by prompting Codex with the Nango skill (type &lt;code&gt;$&lt;/code&gt; to mention a skill, or run &lt;code&gt;/skills&lt;/code&gt; to browse):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$building-nango-functions-locally Build a Nango sync for the google-sheet integration that imports
the rows of the spreadsheet a customer connects and keeps them up to date, refreshing every hour.
Integrate it with my frontend.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the skill loaded, Codex:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Researches the Sheets API and the endpoints it needs.&lt;/li&gt;
&lt;li&gt;Writes the sync and a typed model for your rows.&lt;/li&gt;
&lt;li&gt;Tests it against your real connection with &lt;code&gt;nango dryrun&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Iterates on any errors until the sync works end to end.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbd7ldignrgdvvzrazf6h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbd7ldignrgdvvzrazf6h.gif" alt="Codex building the fetch-spreadsheet-rows sync with the Nango skill and testing it against the real connection" width="560" height="484"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Codex generates this sync. You do not write it by hand.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;createSync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Imports rows from the connected Google Sheet and refreshes them every hour.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;every hour&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;autoStart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// starts once your app saves the spreadsheetId metadata&lt;/span&gt;
    &lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SheetRow&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;spreadsheetId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMetadata&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/v4/spreadsheets/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;spreadsheetId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/values/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;batchSave&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;toRows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SheetRow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full sync, with the row model, header mapping, and delete tracking, is in the demo repo: &lt;a href="https://github.com/NangoHQ/google-sheets-api-integration/blob/main/nango-integrations/google-sheet/syncs/fetch-spreadsheet-rows.ts" rel="noopener noreferrer"&gt;&lt;code&gt;fetch-spreadsheet-rows.ts&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When Codex finishes, it deploys the sync for you (approve the deploy when it asks):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nango deploy &lt;span class="nt"&gt;--sync&lt;/span&gt; fetch-spreadsheet-rows dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the prompt said to integrate the frontend, Codex also wires &lt;a href="https://nango.dev/docs/guides/auth/auth-guide" rel="noopener noreferrer"&gt;Nango Connect&lt;/a&gt; into your app: customers authorize Google Sheets, paste their spreadsheet link, and the sync starts on its own.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklr9ygk9r0qbvuqq48hf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklr9ygk9r0qbvuqq48hf.gif" alt="Connecting a Google account in the demo app with Nango Connect and watching the spreadsheet rows sync in" width="600" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your backend reads the synced rows from Nango’s cache and serves them to your UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;records&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listRecords&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;providerConfigKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;google-sheet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;connectionId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SheetRow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do a quick check to confirm everything works: open your app, connect a Google account, paste a spreadsheet URL, and watch the rows appear. Codex has already tested the integration with &lt;code&gt;nango dryrun&lt;/code&gt;; this is your own sanity check.&lt;/p&gt;

&lt;h3&gt;
  
  
  Letting users pick a Google Sheet
&lt;/h3&gt;

&lt;p&gt;The Sheets API has no endpoint to list a user’s spreadsheets, so the sync needs to be told which one to read. Here we handle it by asking the user for the spreadsheet URL. If you would rather let customers pick from a list of their spreadsheets than paste a link, use the Google Drive API: a Drive-scoped connection plus a file picker, which we will cover in a separate Google Drive guide.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run the sync on demand
&lt;/h3&gt;

&lt;p&gt;Syncs run on a schedule (every hour in this example). When a customer wants fresh data immediately, give them a refresh button that triggers the sync on demand (behind the scenes, a &lt;code&gt;nango.triggerSync&lt;/code&gt; call) instead of waiting for the next run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$building-nango-functions-locally Add a refresh button to my app that triggers the fetch-spreadsheet-rows
sync on demand for the current user's connection.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr81196hcqdvj9eoihxk6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr81196hcqdvj9eoihxk6.jpg" alt="Flow of the Google Sheets integration: a customer authorizes via Nango Connect, the fetch-spreadsheet-rows sync polls their rows from the Sheets API into Nango's cache for your backend, and the append-row action writes rows back" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the sync deployed, a customer connects once and the rows they maintain in Sheets show up in your app and stay current: a product catalog they edit in a spreadsheet, a price list your billing features read, or the roster behind your scheduling screens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Append rows to a customer’s spreadsheet from your app
&lt;/h2&gt;

&lt;p&gt;An &lt;a href="https://nango.dev/docs/guides/functions/action-functions" rel="noopener noreferrer"&gt;action&lt;/a&gt; is a one-off operation your product or an agent triggers on demand. Here it writes back: each new lead, order, or form response in your app lands as a row in the customer’s sheet. Prompt Codex to build it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$building-nango-functions-locally Add an action to the google-sheet integration that appends a row
to the customer's connected spreadsheet from typed input.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3fvespmjd0cfkb5q0pk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3fvespmjd0cfkb5q0pk.png" alt="Prompting Codex with the Nango skill to add the append-row action to the google-sheet integration" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Codex writes the action, tests it by appending real rows to your connected test spreadsheet, and deploys it when you approve.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Codex generates this action; approve the deploy when it asks.&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;createAction&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Append a row to the connected spreadsheet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// appends are not idempotent, a retry must not duplicate the row&lt;/span&gt;
    &lt;span class="na"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/v4/spreadsheets/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spreadsheetId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/values/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;:append`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;valueInputOption&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USER_ENTERED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;insertDataOption&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INSERT_ROWS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;updatedRange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updatedRange&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two parameters matter here: &lt;code&gt;valueInputOption=USER_ENTERED&lt;/code&gt; parses values the way the Sheets UI would (so a date string becomes a real date), and &lt;code&gt;insertDataOption=INSERT_ROWS&lt;/code&gt; inserts new rows instead of overwriting data below the table. If your customers store values that look like numbers but aren’t (phone numbers, zip codes), switch to &lt;code&gt;RAW&lt;/code&gt;. On &lt;code&gt;retries: 0&lt;/code&gt;: a rate-limited request is safe to retry because it wrote nothing, and Nango’s proxy handles that; re-running the whole action after an unknown failure could append the row twice, so the action itself does not retry.&lt;/p&gt;

&lt;p&gt;Deploy it the same way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nango deploy &lt;span class="nt"&gt;--action&lt;/span&gt; append-row dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can test the action from your app, or run it from the Nango dashboard with the &lt;a href="https://nango.dev/docs/updates/changelog#playground" rel="noopener noreferrer"&gt;Playground&lt;/a&gt; against your connection. The demo wires one more action of the same shape for inline edits, so changing a row in the app updates the sheet:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjhidgjc6rmwkzshvamn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjhidgjc6rmwkzshvamn.gif" alt="Editing a row in the demo app writes the change back to the customer's Google Sheet" width="600" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your product can now write to the spreadsheets your customers already work in. Form builders use this exact pattern to stream responses into a sheet, schedulers log bookings as they happen, and e-commerce tools export each order as it comes in, without the customer ever downloading a CSV.&lt;/p&gt;

&lt;h2&gt;
  
  
  Export app data to a new spreadsheet
&lt;/h2&gt;

&lt;p&gt;The other common write pattern is an “Export to Google Sheets” button: instead of appending to an existing sheet, your app creates a fresh spreadsheet in the customer’s account and fills it with data. The same action workflow covers it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$building-nango-functions-locally Add an action to the google-sheet integration that creates a new
spreadsheet from a title and a 2-D array of values, and returns the new spreadsheet's URL.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Codex builds this on two calls, &lt;code&gt;spreadsheets.create&lt;/code&gt; followed by a &lt;code&gt;values.batchUpdate&lt;/code&gt; write, and returns the &lt;code&gt;spreadsheetUrl&lt;/code&gt; your UI can open in a new tab. Analytics exports, scheduled report generation, and one-report-sheet-per-customer setups are all this action plus a place to trigger it from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give AI agents in your product access to customer spreadsheets
&lt;/h2&gt;

&lt;p&gt;Once the sync and actions are deployed, the AI agents inside your product can use them. Nango exposes enabled actions as typed tool calls through a hosted &lt;a href="https://nango.dev/docs/guides/functions/tool-calling" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;, so an agent calls &lt;code&gt;append-row&lt;/code&gt; with typed inputs instead of guessing raw Sheets API parameters.&lt;/p&gt;

&lt;p&gt;Point your MCP client at Nango’s server (Streamable HTTP transport) and pass three values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization:        Bearer &amp;lt;YOUR-NANGO-SECRET-KEY&amp;gt;
provider-config-key:  google-sheet
connection-id:        &amp;lt;CONNECTION-ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authorization:&lt;/strong&gt; your Nango secret key, held by your backend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;provider-config-key:&lt;/strong&gt; your Google Sheets integration ID (&lt;code&gt;google-sheet&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;connection-id:&lt;/strong&gt; the connection for the current user. Fetch it per logged-in user rather than hardcoding it, so each user’s agent acts on their own spreadsheets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Codex can wire this into your product’s agent for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$building-nango-functions-locally Wire my product's AI agent to Nango's MCP server for the google-sheet
integration, passing the logged-in user's connection id, so it can read and append spreadsheet rows.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlqxx79uoxzlvoue8yd5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlqxx79uoxzlvoue8yd5.gif" alt="The demo app's assistant updating the customer's spreadsheet through tool calls to Nango's MCP server" width="600" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you do not have an agent interface in your product yet but want to try the tools, add Nango’s MCP server to Codex itself. &lt;code&gt;codex mcp add&lt;/code&gt; does not support custom headers, so add it to &lt;code&gt;~/.codex/config.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[mcp_servers.nango_sheets]&lt;/span&gt;
&lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://api.nango.dev/mcp"&lt;/span&gt;
&lt;span class="py"&gt;bearer_token_env_var&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"NANGO_SECRET_KEY"&lt;/span&gt;
&lt;span class="py"&gt;http_headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;"connection-id"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;CONNECTION-ID&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;"provider-config-key"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"google-sheet"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then ask Codex: “Append a row with today’s signup count to my Metrics spreadsheet using the nango sheets MCP.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; you can view detailed action and sync logs on the Nango dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2v920gcok0yu0t8hdzc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2v920gcok0yu0t8hdzc.png" alt="Nango logs showing successful google-sheet sync and action runs" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your product’s agents can now work with customer spreadsheets through the same integration: an in-product assistant answers questions from the synced rows, a support copilot logs each resolution to the customer’s tracking sheet, all scoped to that user’s connection and logged like every other call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common issues
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Cause and fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Unable to parse range: Sheet1!A1:D10&lt;/code&gt; (400)&lt;/td&gt;
&lt;td&gt;The tab was renamed, or the sheet name needs single quotes (&lt;code&gt;'Q2 Leads'!A1:D10&lt;/code&gt;). Store the numeric &lt;code&gt;sheetId&lt;/code&gt; and resolve the current tab name with &lt;code&gt;spreadsheets.get&lt;/code&gt; before building ranges.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;429 &lt;code&gt;Quota exceeded for quota metric 'Read requests'&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The Sheets API allows 60 requests per minute per user. Batch with &lt;code&gt;values.batchGet&lt;/code&gt; / &lt;code&gt;values.batchUpdate&lt;/code&gt;; Nango retries with backoff for you.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;403 &lt;code&gt;The caller does not have permission&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The connected account lost access to the spreadsheet, or was not granted access in the first place. Reconnect with the owning account or re-share the sheet.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400 &lt;code&gt;This operation is not supported for this document&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The ID points to an Excel file stored in Drive, not a native Google Sheet. Convert it (File &amp;gt; Save as Google Sheets) and use the new ID.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Numbers or dates change when written&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;USER_ENTERED&lt;/code&gt; parses values like the Sheets UI, so "06-11" can become a date. Use &lt;code&gt;RAW&lt;/code&gt; to store values verbatim.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Appended rows land in the wrong place&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;values.append&lt;/code&gt; writes after the last "table" it finds in the range, and blank rows split tables. Keep data contiguous and check the &lt;code&gt;tableRange&lt;/code&gt; field in the response.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refresh token stops working after 7 days&lt;/td&gt;
&lt;td&gt;Your Google OAuth app is in Testing mode. Publish it to Production and complete verification; see Google OAuth invalid_grant: what it means and how to fix it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;listRecords&lt;/code&gt; is empty right after connecting&lt;/td&gt;
&lt;td&gt;The sync starts only after your app saves the &lt;code&gt;spreadsheetId&lt;/code&gt; metadata, and the first run is asynchronous. Read records once a run completes (Codex wires this into your app).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;A production-grade Google Sheets API integration comes down to customer OAuth (sensitive scopes and Google verification), reading rows durably (a polling sync, since the API has no webhooks), writing rows safely (append semantics and value parsing), and staying inside per-user quotas.&lt;/p&gt;

&lt;p&gt;With the Nango skill, Codex writes that logic as code from a prompt and tests it against a real connection, while Nango’s runtime handles managed OAuth, durable syncs, retries, and observability. The same workflow covers any of Nango’s &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;800+ supported APIs&lt;/a&gt;, and it scales into &lt;a href="https://nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;just-in-time integrations&lt;/a&gt;: integrations built on demand by an agent instead of pre-built for every use case.&lt;/p&gt;

&lt;p&gt;Clone the &lt;a href="https://github.com/NangoHQ/google-sheets-api-integration" rel="noopener noreferrer"&gt;demo project on GitHub&lt;/a&gt; to run it end to end, or build your first integration from the &lt;a href="https://nango.dev/docs/getting-started/quickstart" rel="noopener noreferrer"&gt;quickstart&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/how-to-build-a-notion-api-integration-using-nango-and-claude" rel="noopener noreferrer"&gt;How to build a Notion API integration with Nango and Claude&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/how-to-build-a-gmail-api-integration-with-nango-and-claude" rel="noopener noreferrer"&gt;How to build a Gmail API integration with Nango and Claude&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/how-to-build-a-real-time-google-calendar-api-integration" rel="noopener noreferrer"&gt;How to build a real-time Google Calendar API integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/google-oauth-invalid-grant-token-has-been-expired-or-revoked" rel="noopener noreferrer"&gt;Google OAuth invalid_grant: what it means and how to fix it&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/best-api-integration-platforms-claude-code-cursor-codex" rel="noopener noreferrer"&gt;Best API integration platforms to use with Claude Code, Cursor, and Codex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/nango-api-integrations-builder-skill" rel="noopener noreferrer"&gt;Introducing the Nango API integrations builder skill&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/using-ai-coding-agents-for-building-api-integrations" rel="noopener noreferrer"&gt;Using AI coding agents for building API integrations in 2026&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>integrations</category>
      <category>googlesheet</category>
      <category>oauth</category>
    </item>
    <item>
      <title>Best self-hosted API integration platforms for AI agents</title>
      <dc:creator>Sapnesh Naik</dc:creator>
      <pubDate>Wed, 10 Jun 2026 19:49:50 +0000</pubDate>
      <link>https://dev.to/nangohq/best-self-hosted-api-integration-platforms-for-ai-agents-42lm</link>
      <guid>https://dev.to/nangohq/best-self-hosted-api-integration-platforms-for-ai-agents-42lm</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;AI agents and SaaS products need API integrations with their customers’ tools: read a record from the CRM, post to Slack, draft an email, update a ticket. An integration platform handles the auth, credential storage, and execution behind those calls. On a managed platform, all of that runs on the vendor’s cloud.&lt;/p&gt;

&lt;p&gt;Teams in regulated industries, or with data-residency rules or strict security reviews, need a self-hosted integration platform where credentials and execution stay on their own infrastructure.&lt;/p&gt;

&lt;p&gt;The platforms compared:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nango:&lt;/strong&gt; The integration platform where coding agents build API integrations and AI agents consume them. Open source, with a free self-hosted edition for auth and the API proxy, and Enterprise self-hosting that runs the full platform in your own cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composio:&lt;/strong&gt; A managed tool-calling platform with a large catalog. Their GitHub repo is only the SDK; the runtime that stores credentials is closed source, and self-hosting is an Enterprise-only option that goes through sales.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paragon:&lt;/strong&gt; A low-code embedded iPaaS whose full runtime can run in your own Kubernetes. Self-hosting needs a quote-based Enterprise license, and the closed-source images contact Paragon’s cloud for license checks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arcade.dev:&lt;/strong&gt; An MCP (Model Context Protocol) runtime with per-user auth for agents. The engine is a closed-source binary and full self-hosting is enterprise-only. The documented on-prem pattern still routes through Arcade’s cloud.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why self-host an API integration platform
&lt;/h2&gt;

&lt;p&gt;An integration platform holds three sensitive things: the OAuth tokens and API keys for your customers’ accounts, the data those APIs return, and the code that runs against them. Most teams are fine letting a managed cloud hold all three. For some, that is ruled out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regulated industries:&lt;/strong&gt; Healthcare, finance, and government workloads often cannot pass customer credentials or data through a third-party processor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data residency:&lt;/strong&gt; Some jurisdictions require data to stay in a region, or a network, that you control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security review and procurement:&lt;/strong&gt; “Where do our customers’ Salesforce tokens live?” is an easier question in a vendor review when the answer is “in our own VPC.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Air-gapped or private networks:&lt;/strong&gt; Some deployments have no route to a public SaaS API at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Open-source SDK vs self-hostable runtime
&lt;/h2&gt;

&lt;p&gt;Most platforms in this space have a public GitHub repo. In most cases, the repo contains a client SDK, a CLI, or an MCP wrapper. The backend that stores tokens, runs OAuth flows, and executes integration code is either closed source behind an enterprise license or not available at all.&lt;/p&gt;

&lt;p&gt;Self-hosting comes in three tiers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free self-hosting:&lt;/strong&gt; You deploy a working edition from public images without talking to sales.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise-licensed self-hosting:&lt;/strong&gt; The full runtime runs in your cloud, but only with a license key from the vendor’s sales team.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not self-hostable:&lt;/strong&gt; The runtime only exists as managed SaaS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;License terms matter as much as deployment. The part you run may be MIT or Apache-2.0 while the part that holds credentials is proprietary. Some licenses also prohibit embedding the tool in a commercial product.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to look for in a self-hosted integration platform for AI agents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A self-hostable runtime:&lt;/strong&gt; Auth, credential storage, and execution can run on your infrastructure. Check what unlocks it: a free edition you can deploy yourself, or an enterprise license that starts with a sales call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;White-label, per-customer auth:&lt;/strong&gt; Each of your customers connects their own account under your brand, with token refresh handled for you. Check where tokens are stored and which domain appears in the OAuth callback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP and typed tool calls:&lt;/strong&gt; Agents discover and call tools over the &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt; or a REST API, with strict input and output schemas so the model does not guess parameters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A way for coding agents to build integrations:&lt;/strong&gt; A skill that lets Claude Code, Cursor, or Codex write a new integration and test it against a real connection, instead of only consuming a fixed catalog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More than tool calls:&lt;/strong&gt; Data syncs keep agent context fresh, webhooks let agents react to events, and per-customer configuration handles tenant-specific behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation, observability, and compliance:&lt;/strong&gt; Per-tenant isolation, full request and response logs, and the certifications (SOC 2, GDPR, HIPAA) that regulated buyers ask about.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The best self-hosted API integration platforms in 2026
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Nango
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nango.dev" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; is the integration platform where coding agents build integrations. Engineers, or coding agents like Claude Code, Cursor, and Codex, write integrations as code in your repo. Nango’s runtime executes them securely and at scale, covering auth, tool calls, data syncs, and webhooks across &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;800+ APIs&lt;/a&gt;. It is &lt;a href="https://github.com/NangoHQ/nango" rel="noopener noreferrer"&gt;open source&lt;/a&gt; under the Elastic License 2.0: you can self-host it and embed it in your product, but not resell Nango as a managed service. Hundreds of &lt;a href="https://nango.dev/customers" rel="noopener noreferrer"&gt;fast-growing AI companies&lt;/a&gt; use it as core infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxstj222ohi4oab4muqw9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxstj222ohi4oab4muqw9.gif" alt="Nango API integrations catalog with 800+ supported providers" width="760" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On self-hosting:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nango offers two &lt;a href="https://nango.dev/docs/guides/platform/self-hosting" rel="noopener noreferrer"&gt;self-hosting&lt;/a&gt; paths. A free self-hosted edition deploys with docker-compose and covers managed auth and the API proxy. Enterprise self-hosting deploys the full platform with Helm charts on your own AWS, GCP, or Azure. It runs the same architecture as Nango Cloud: five Node services plus Postgres, Redis, object storage, and Elasticsearch, sized for 1M+ executions per day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa8gscghf4lgxplqorx4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa8gscghf4lgxplqorx4u.png" alt="How Nango works: your product and coding agents connect to external APIs through Nango" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams building AI agents or SaaS products that need API integrations with their customers’ tools, with credentials and execution on infrastructure they control. Coding agents build the integrations, and the agents and features in your product consume them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Credentials stay yours, encrypted with your key:&lt;/strong&gt; Self-hosted deployments require your own encryption key (the &lt;code&gt;NANGO_ENCRYPTION_KEY&lt;/code&gt; environment variable) to encrypt credentials and cached records at rest. Tokens live in your Postgres, encrypted with a key Nango never holds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI builder skill for 18+ coding agents:&lt;/strong&gt; One command installs the skill. It gives Claude Code, Cursor, Codex, Gemini CLI, and others the context to research an API, write the integration, and test it against a real connection. See the walkthrough of &lt;a href="https://nango.dev/blog/how-to-build-a-real-time-google-calendar-api-integration" rel="noopener noreferrer"&gt;building a real-time Google Calendar integration&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install the Nango skill for your coding agent&lt;/span&gt;
npx skills add NangoHQ/skills &lt;span class="nt"&gt;-s&lt;/span&gt; building-nango-functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ZG597mH9ZDg"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Built-in MCP server and typed tool calls:&lt;/strong&gt; Every action is a deterministic &lt;a href="https://nango.dev/docs/guides/functions/tool-calling" rel="noopener noreferrer"&gt;tool call&lt;/a&gt; over both a REST API and a hosted MCP server at &lt;code&gt;https://api.nango.dev/mcp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data syncs and webhooks included:&lt;/strong&gt; Durable incremental syncs keep data fresh for RAG, webhook processing reacts to provider events in real time, and &lt;a href="https://nango.dev/docs/getting-started/use-cases/customer-configuration" rel="noopener noreferrer"&gt;per-customer configuration&lt;/a&gt; adapts behavior per tenant without forking code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;White-label auth across 800+ APIs:&lt;/strong&gt; A drop-in Connect UI handles OAuth, API keys, JWT, basic auth, and MCP Auth, with token refresh built in. Your end users authorize under your brand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability built for agents:&lt;/strong&gt; Every operation produces &lt;a href="https://nango.dev/docs/guides/platform/observability" rel="noopener noreferrer"&gt;structured logs&lt;/a&gt; with full request and response details, exported through OpenTelemetry. A coding agent can read a failing run and ship a fix on its own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz3ewrpmwhbtgdg5n3w2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz3ewrpmwhbtgdg5n3w2.png" alt="Nango observability dashboard showing detailed API integration logs" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Just-in-time integrations:&lt;/strong&gt; Since June 2026, the remote function builder lets coding agents build and deploy actions, syncs, and webhook handlers from a single prompt, without a local project. See &lt;a href="https://nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;the emergence of just-in-time integrations&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise compliance:&lt;/strong&gt; &lt;a href="https://trust.nango.dev" rel="noopener noreferrer"&gt;SOC 2 Type II, GDPR, and HIPAA&lt;/a&gt;, with a BAA available on request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The free self-hosted edition covers auth and the proxy only:&lt;/strong&gt; Functions, syncs, webhooks, and the MCP server require Enterprise self-hosting or Nango Cloud. Nango documents this split openly on the &lt;a href="https://nango.dev/docs/guides/platform/self-hosting#free-self-hosting" rel="noopener noreferrer"&gt;self-hosting page&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Composio
&lt;/h3&gt;

&lt;p&gt;Composio is a managed tool-calling platform for AI agents. It offers a catalog of 1,000+ apps, MIT-licensed Python and TypeScript SDKs with adapters for the popular agent frameworks, and managed per-user auth.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7y8q37y05dj8hpsf0gs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7y8q37y05dj8hpsf0gs.png" alt="Composio platform overview" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On self-hosting:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Composio’s main GitHub repo contains the SDKs and a CLI, not the platform. The backend that stores credentials and executes tool calls is closed source.&lt;/p&gt;

&lt;p&gt;Composio publishes official Helm charts for the platform, but the charts pull closed-source images from a registry tied to an Enterprise license.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that want a large hosted catalog of agent tools on a managed runtime. A fit if you are prepared to sign an enterprise contract later, when credentials need to move on-prem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large catalog:&lt;/strong&gt; 1,000+ apps, with Tool Router routing across the catalog to keep agent context small.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIT-licensed SDKs with broad framework support:&lt;/strong&gt; OpenAI, Anthropic, LangChain, CrewAI, Vercel AI SDK, and others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed per-user auth:&lt;/strong&gt; Connected accounts are scoped to your user IDs, with automatic token refresh. SOC 2 Type II and ISO 27001 certified.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Closed-source runtime:&lt;/strong&gt; The credential store and execution services have no public source. A GitHub request for self-serve self-hosting has been open since July 2024, answered only with “part of our paid offering.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Credentials always pass through Composio’s cloud on self-serve plans:&lt;/strong&gt; Even with your own OAuth app, the documented setup registers Composio’s backend callback URL with the provider. Composio’s cloud captures and stores the tokens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifvy5fc3b3wyka5jdo3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifvy5fc3b3wyka5jdo3u.png" alt="Composio OAuth consent screen showing Composio branding" width="757" height="995"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No data syncs:&lt;/strong&gt; Triggers exist, but there is no managed sync infrastructure for keeping customer data fresh for RAG.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No path to deploy your own connectors:&lt;/strong&gt; Custom tools are marked experimental and run in-process in your own app. Coding agents can consume the catalog but not extend it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a detailed comparison, see the &lt;a href="https://nango.dev/blog/composio-vs-nango" rel="noopener noreferrer"&gt;Composio vs Nango head-to-head&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Paragon
&lt;/h3&gt;

&lt;p&gt;Paragon is an embedded integration platform for B2B SaaS. It combines a white-label Connect Portal, a visual workflow builder, and Managed Sync for data ingestion. It also exposes 1,000+ pre-built actions as tools for AI agents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxyojvlxiryb3sq1xfvlw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxyojvlxiryb3sq1xfvlw.png" alt="Paragon visual workflow builder" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On self-hosting:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Paragon’s full runtime is self-hostable, which is rare among embedded iPaaS vendors, but it is Enterprise-only. The public installer repo deploys the platform onto Kubernetes in your AWS, GCP, or Azure account with Terraform and Helm. It requires a license key from Paragon’s sales team and a Docker account with read access to Paragon’s private image registries.&lt;/p&gt;

&lt;p&gt;Once deployed, the data plane stays local: the docs state the applications never export or sync data outside the installation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnnpx5smhtd6vj3c85hli.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnnpx5smhtd6vj3c85hli.png" alt="Paragon enterprise-installer prerequisites requiring a license key and private registry access" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise B2B SaaS teams that want an embedded iPaaS with a visual builder and managed data sync, deployed in their own VPC. A fit if you have the budget and DevOps capacity for a quote-based Enterprise deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Full runtime in your cloud:&lt;/strong&gt; Auth, credentials, workflows, and sync run in your cloud, with credentials stored in your own Postgres.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed deployment option:&lt;/strong&gt; Paragon’s team can operate the stack inside your cloud account. Most of their self-hosted customers use this option.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent tooling on top of the platform:&lt;/strong&gt; ActionKit exposes pre-built actions and triggers as LLM tools, with an official MCP server. HIPAA support for self-hosted installs was added in January 2026.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise-only and quote-based:&lt;/strong&gt; There is no free or self-serve way to run the runtime. Nothing boots without a license key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Closed source with vendor-controlled installers:&lt;/strong&gt; You deploy opaque images from private registries. The public Terraform and Helm assets carry no open-source license, and the README warns that modified charts may not be supported.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-hosted installs depend on Paragon’s licensing service:&lt;/strong&gt; The services contact Paragon’s cloud on bootup and on a periodic cron to verify the license.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heavy operational footprint:&lt;/strong&gt; An unmanaged install runs a Kubernetes cluster, three Postgres databases, Redis clusters, and MinIO, with your team owning monitoring and upgrades.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low-code customization only:&lt;/strong&gt; The catalog is 130+ connectors, and custom work routes through Paragon’s dashboard and low-code tooling. A coding agent cannot extend the platform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a detailed comparison, see &lt;a href="https://nango.dev/blog/paragon-vs-nango" rel="noopener noreferrer"&gt;Paragon vs Nango&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Arcade.dev
&lt;/h3&gt;

&lt;p&gt;Arcade is an MCP runtime for agent tool calling, built around per-user auth. When a tool call lacks a user grant, the Arcade Engine intercepts it, runs the OAuth flow with the end user, and stores and refreshes the tokens. Credentials never enter the LLM context. The tool-building framework is open source under MIT.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2nheesdmelebv7ivtoo9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2nheesdmelebv7ivtoo9.png" alt="Arcade platform overview" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On self-hosting:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arcade’s Engine, which holds tokens and routes tool calls, is a closed-source binary with no public repo. Full platform self-hosting exists only as part of the enterprise offering, and the pricing page does not mention self-hosting on any tier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1h48x5df29lmifi7mire.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1h48x5df29lmifi7mire.png" alt="Arcade docs showing on-premise deployments are part of the enterprise offering" width="799" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams building MCP-first agents where per-user authorization is the priority. Best suited if tool calls are your entire scope and you do not need data syncs or webhooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Per-user OAuth built for agents:&lt;/strong&gt; Authorization is checked before execution, the user is prompted to grant access, and tokens never enter the model context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP-native with an open-source framework:&lt;/strong&gt; Hosted MCP servers, streamable HTTP transport, and an MIT framework for building custom servers, with skills for Claude Code and Cursor that scaffold new tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Co-authored the MCP auth spec:&lt;/strong&gt; Worked with Anthropic on the MCP secure authorization capability, announced in November 2025.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Engine is closed source:&lt;/strong&gt; The exact component that stores end-customer credentials and routes authenticated tool calls has no public repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full self-hosting is enterprise-only:&lt;/strong&gt; The Helm-based on-prem deployment is sold as part of the enterprise offering, and self-serve install docs were removed in October 2025.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The non-enterprise “on-prem” pattern is hybrid:&lt;/strong&gt; Your MCP server must be reachable from Arcade’s cloud Engine over a public URL, and OAuth tokens stay in Arcade Cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool calls only:&lt;/strong&gt; No data syncs to feed agent context, no webhook ingestion, no scheduled triggers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modest catalog:&lt;/strong&gt; The registry advertises 154 MCP servers, but only 116 are live as of June 2026, and 42 of the live ones are auto-generated.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Side-by-side comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Nango&lt;/th&gt;
&lt;th&gt;Composio&lt;/th&gt;
&lt;th&gt;Paragon&lt;/th&gt;
&lt;th&gt;Arcade.dev&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free self-hosted edition&lt;/td&gt;
&lt;td&gt;Yes (auth + proxy)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full platform on your infra&lt;/td&gt;
&lt;td&gt;Enterprise plan&lt;/td&gt;
&lt;td&gt;Enterprise plan&lt;/td&gt;
&lt;td&gt;Enterprise plan&lt;/td&gt;
&lt;td&gt;Enterprise plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open-source runtime&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credentials on your infra&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Enterprise only&lt;/td&gt;
&lt;td&gt;Enterprise only&lt;/td&gt;
&lt;td&gt;Enterprise only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding agents build integrations&lt;/td&gt;
&lt;td&gt;Yes (18+ agents)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No (low-code only)&lt;/td&gt;
&lt;td&gt;Limited (scaffolding)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP tool calls&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data syncs and triggers&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Triggers only&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Catalog&lt;/td&gt;
&lt;td&gt;800+ APIs, 2000+ prebuilt actions&lt;/td&gt;
&lt;td&gt;1,000+ apps&lt;/td&gt;
&lt;td&gt;130+ connectors&lt;/td&gt;
&lt;td&gt;116 MCP servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compliance&lt;/td&gt;
&lt;td&gt;SOC 2 Type II, GDPR, HIPAA&lt;/td&gt;
&lt;td&gt;SOC 2 Type II, ISO 27001&lt;/td&gt;
&lt;td&gt;SOC 2 Type II, GDPR, HIPAA&lt;/td&gt;
&lt;td&gt;Not publicly listed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary focus&lt;/td&gt;
&lt;td&gt;Build + run agentic integrations&lt;/td&gt;
&lt;td&gt;Hosted tool catalog&lt;/td&gt;
&lt;td&gt;Embedded iPaaS&lt;/td&gt;
&lt;td&gt;Tool-calling auth runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Catalog counts use each vendor’s own unit (APIs, apps, connectors, MCP servers) and are not directly comparable.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to choose
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You want to try self-hosting for free before an enterprise contract:&lt;/strong&gt; Pick Nango. It is the only platform in this comparison with a free self-hosted edition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need credentials and execution on your own infrastructure, for an app and the AI agents inside it:&lt;/strong&gt; Pick Nango. It is the only platform here where coding agents build integrations on a runtime you can self-host, and the only one with data syncs and webhooks built in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want a visual workflow builder in your VPC and have an enterprise budget:&lt;/strong&gt; Paragon, if you accept the closed-source runtime and the license checks against Paragon’s cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-user authorization for MCP tool calling is your hardest problem:&lt;/strong&gt; Arcade.dev, if tool calls are the only scope.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can you self-host Composio?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Only on the Enterprise plan. Composio publishes official Helm charts on GitHub, but the platform images are closed source and pulled from a registry tied to an enterprise license, and the docs have no self-hosting section. On self-serve plans, all credentials are stored on Composio’s cloud. See the &lt;a href="https://nango.dev/blog/composio-alternatives" rel="noopener noreferrer"&gt;Composio alternatives&lt;/a&gt; post for the wider comparison.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are Prismatic, Pipedream Connect, or Merge self-hostable?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Prismatic offers an Enterprise-plan private cloud, but Prismatic’s own team deploys and operates it in your AWS account, and its on-prem agent is a connectivity proxy, not the runtime. Pipedream (acquired by Workday in November 2025) publishes connector components on GitHub while the Connect runtime stays fully managed. Merge runs as managed cloud only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can you use n8n or Activepieces for customer-facing product integrations?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both are built for internal workflow automation, and their licenses reflect that. n8n’s Sustainable Use License limits use to internal business purposes, so embedding it in a customer-facing product requires a separate commercial license. Activepieces has an MIT core, but embedding and white-label features sit in its paid enterprise edition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between self-hosted, open source, and on-premise?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Self-hosted means you run the software on infrastructure you control; on-premise is the stricter subset where it runs in your data center. Open source describes the license, not the deployment. A platform can be open source yet cloud-only in practice, because the published code is just an SDK. Self-hostable software can also be fully closed source, like Paragon. Always check which components the open-source license covers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the best self-hosted integration platform for AI agents?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nango is the strongest option for AI agents in 2026. It is open source, the free self-hosted edition keeps auth and credentials on your infrastructure, and Enterprise self-hosting runs the full platform (MCP server, tool calls, data syncs, webhooks) in your own cloud with your own encryption key. It is also the only platform in this comparison where coding agents build and test integrations end to end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Self-hosting rules out most of the API integration market. Many platforms publish an open-source SDK while the credential store and runtime stay on the vendor’s cloud. The rest gate self-hosting behind an enterprise sales process: Paragon’s closed-source runtime needs a quote-based license, and Composio and Arcade.dev reserve full self-hosting for enterprise contracts.&lt;/p&gt;

&lt;p&gt;Nango is the broadest option of the four. The platform is open source, and the free self-hosted edition keeps customer credentials on your infrastructure from day one. Enterprise self-hosting runs the complete platform (auth, tool calls, syncs, webhooks, and the MCP server) in your own cloud. Coding agents build the integrations, and the AI agents in your product consume them.&lt;/p&gt;

&lt;p&gt;If you want to try the Nango AI builder skill with your favorite coding agent, follow the &lt;a href="https://nango.dev/docs/guides/functions/functions-guide" rel="noopener noreferrer"&gt;Nango functions guide&lt;/a&gt; to get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/best-agentic-api-integrations-platform" rel="noopener noreferrer"&gt;Best agentic API integrations platform in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/best-api-integration-platforms-claude-code-cursor-codex" rel="noopener noreferrer"&gt;Best API integration platforms to use with Claude Code, Cursor, and Codex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/best-ai-agent-integration-platforms" rel="noopener noreferrer"&gt;Best AI agent integration platforms to consider in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/composio-alternatives" rel="noopener noreferrer"&gt;Best Composio alternatives for AI agent integrations in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;The emergence of just-in-time integrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/how-nango-runs-untrusted-customer-code-at-scale" rel="noopener noreferrer"&gt;How Nango runs untrusted customer code at scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/guide-to-secure-ai-agent-api-authentication" rel="noopener noreferrer"&gt;A guide to secure AI agent API authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/why-ai-agents-meed-an-integrations-platform" rel="noopener noreferrer"&gt;Why AI agents need an integrations platform&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>agents</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Best integration platform for mail and calendar integrations (2026)</title>
      <dc:creator>Sapnesh Naik</dc:creator>
      <pubDate>Wed, 03 Jun 2026 13:48:46 +0000</pubDate>
      <link>https://dev.to/nangohq/best-integration-platform-for-mail-and-calendar-integrations-2026-2mf0</link>
      <guid>https://dev.to/nangohq/best-integration-platform-for-mail-and-calendar-integrations-2026-2mf0</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;If you need email and calendar API integrations in your product, building them involves handling OAuth across Google, Microsoft, and IMAP, incremental sync, and push notifications. This post compares the platforms teams use to build mail and calendar integrations in 2026.&lt;/p&gt;

&lt;p&gt;We rank them on provider coverage, how you build integrations with each one (including AI coding agent support), how much of the underlying API you can reach, who owns auth, and what else the platform can integrate when mail and calendar are no longer enough.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nango:&lt;/strong&gt; The integration platform where coding agents build integrations. It covers mail and calendar alongside 800+ other APIs, with full API access and auth you own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nylas:&lt;/strong&gt; Unified API for email, calendar, and contacts. Limited to communications data, and your users’ tokens live on Nylas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aurinko:&lt;/strong&gt; A pass-through alternative to Nylas with the same mailbox scope. Owns the OAuth app your users authorize.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unipile:&lt;/strong&gt; A unified API built around messaging (LinkedIn, WhatsApp), with email and calendar added on.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why mail and calendar API integrations are hard
&lt;/h2&gt;

&lt;p&gt;If you’re integrating mail and calendar, you’re either looking at Google, Microsoft, Apple or generic IMAP. Each models the data differently, and none offers a simple “subscribe and get updates” endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For email:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sending needs raw MIME, not JSON:&lt;/strong&gt; the Gmail API wants a base64url-encoded RFC 2822 MIME message in a &lt;code&gt;raw&lt;/code&gt; field, not a &lt;code&gt;to&lt;/code&gt;/&lt;code&gt;subject&lt;/code&gt;/&lt;code&gt;body&lt;/code&gt; object (&lt;a href="https://developers.google.com/workspace/gmail/api/guides/sending" rel="noopener noreferrer"&gt;Gmail docs&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incremental sync is stateful and expires:&lt;/strong&gt; Gmail tracks changes with a &lt;code&gt;historyId&lt;/code&gt; that expires after about a week, and once it ages out you get a &lt;code&gt;404&lt;/code&gt; and run a full resync (&lt;a href="https://developers.google.com/workspace/gmail/api/guides/sync" rel="noopener noreferrer"&gt;Gmail docs&lt;/a&gt;). Microsoft Graph does the same with per-folder &lt;a href="https://learn.microsoft.com/en-us/graph/delta-query-messages" rel="noopener noreferrer"&gt;delta tokens&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time needs more than a webhook URL:&lt;/strong&gt; Gmail push runs through Google Cloud Pub/Sub, and the &lt;code&gt;watch&lt;/code&gt; must be renewed at least every 7 days (&lt;a href="https://developers.google.com/workspace/gmail/api/guides/push" rel="noopener noreferrer"&gt;Gmail docs&lt;/a&gt;). Microsoft Graph mail subscriptions expire in under 7 days and cap at 1,000 per mailbox (&lt;a href="https://learn.microsoft.com/en-us/graph/change-notifications-overview" rel="noopener noreferrer"&gt;Graph docs&lt;/a&gt;). Plain IMAP has no webhooks at all: you hold a connection open with &lt;code&gt;IDLE&lt;/code&gt; and poll (&lt;a href="https://datatracker.ietf.org/doc/html/rfc2177" rel="noopener noreferrer"&gt;RFC 2177&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restricted scopes need a security review:&lt;/strong&gt; &lt;code&gt;gmail.readonly&lt;/code&gt;, &lt;code&gt;gmail.modify&lt;/code&gt;, and &lt;code&gt;gmail.compose&lt;/code&gt; are restricted scopes that require Google verification plus an annual security assessment before you go live (&lt;a href="https://developers.google.com/workspace/gmail/api/auth/scopes" rel="noopener noreferrer"&gt;Gmail scopes&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For calendars:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sync tokens, then full resets:&lt;/strong&gt; Google Calendar incremental sync uses a &lt;code&gt;syncToken&lt;/code&gt; to fetch only what changed. Google invalidates that token after a period of time, or when too much has changed to return a clean delta. The next call then returns &lt;code&gt;410 Gone&lt;/code&gt;, and you wipe local state and resync from scratch (&lt;a href="https://developers.google.com/workspace/calendar/api/guides/sync" rel="noopener noreferrer"&gt;Calendar docs&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch channels expire with no renew endpoint:&lt;/strong&gt; Google Calendar push channels expire after about a week, with no automatic renewal. You create a new channel before the old one dies (&lt;a href="https://developers.google.com/workspace/calendar/api/guides/push" rel="noopener noreferrer"&gt;Calendar docs&lt;/a&gt;). For 1,000 connected users, that is 1,000 channels to rotate every week.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recurring events and Apple:&lt;/strong&gt; you expand recurring events with &lt;code&gt;singleEvents=true&lt;/code&gt;, and &lt;code&gt;syncToken&lt;/code&gt; cannot be combined with most query parameters. Apple iCloud is CalDAV, which has no push at all (&lt;a href="https://datatracker.ietf.org/doc/html/rfc4791" rel="noopener noreferrer"&gt;RFC 4791&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OAuth tokens need constant maintenance on top of this. Access tokens last about an hour, so you refresh them on every connection. Refresh tokens can break too: when a user changes their password or revokes access. When two requests refresh the same token at once, you also have to handle &lt;a href="https://nango.dev/blog/concurrency-with-oauth-token-refreshes" rel="noopener noreferrer"&gt;concurrency&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is the standard work involved in mail and calendar API integrations, and it is why most teams use an integrations platform rather than building it themselves.&lt;/p&gt;

&lt;p&gt;Tip: If you’re looking for a full build example, see our guides on the &lt;a href="https://nango.dev/blog/how-to-build-a-gmail-api-integration-with-nango-and-claude" rel="noopener noreferrer"&gt;Gmail API&lt;/a&gt; and &lt;a href="https://nango.dev/blog/how-to-build-a-real-time-google-calendar-api-integration" rel="noopener noreferrer"&gt;real-time Google Calendar&lt;/a&gt; integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to look for in a mail and calendar integration platform
&lt;/h2&gt;

&lt;p&gt;Every tool here supports embedded, customer-facing integrations, where each of your users connects their own mailbox or calendar. The differences are in how you build integrations with each one, how much of the API you can reach, and who owns the auth.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Provider coverage:&lt;/strong&gt; Gmail and Google Workspace, Microsoft 365, Outlook, and Exchange, and IMAP at a minimum. Add iCloud (CalDAV) if you need Apple calendars.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How you build integrations:&lt;/strong&gt; the fastest teams now have coding agents (Claude Code, Cursor, Codex) write integrations against real APIs. The platform should ship a skill or harness so an agent can research, write, test, and deploy an integration, not just expose a fixed catalog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How much of the API you can reach:&lt;/strong&gt; a normalized email or calendar schema only exposes the fields most providers share. When you need a provider-specific field or endpoint, you want full API access to reach it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who owns auth and tokens:&lt;/strong&gt; if the tokens live on the vendor’s servers, your users may see the vendor on the consent screen, and migrating off means re-authenticating every account. Prefer a platform where you use your own OAuth app, under your brand, and keep control of the credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time syncs and webhooks:&lt;/strong&gt; durable data syncs plus managed webhook and channel renewal, so the watch rotation and resync recovery are handled for you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What else it integrates:&lt;/strong&gt; most products need more than mail and calendar. Once you add CRM, Slack, ticketing, or storage, a communications-API-only platform means a second vendor. A broad platform covers mail and calendar as one slice of a much larger catalog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code-first and open source:&lt;/strong&gt; integrations that live in your repo, under version control and CI, are easier to review, test, and own than a closed catalog you cannot inspect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability:&lt;/strong&gt; per-request logs and OpenTelemetry export, so you and your coding agent can read a failure and fix it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The 4 best mail and calendar integration platforms
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Nango
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nango.dev" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; is the integration platform where coding agents build integrations. Engineers, or coding agents like Claude Code, Cursor, and Codex, write integrations as code in your repo, and Nango’s cloud runtime runs them securely and at scale.&lt;/p&gt;

&lt;p&gt;The platform covers API auth, tool calls, data syncs, webhooks, and unified APIs across &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;800+ APIs&lt;/a&gt;. For mail and calendar, that means &lt;a href="https://nango.dev/docs/api-integrations/google-mail" rel="noopener noreferrer"&gt;Gmail&lt;/a&gt;, &lt;a href="https://nango.dev/docs/api-integrations/outlook" rel="noopener noreferrer"&gt;Microsoft 365 and Outlook&lt;/a&gt;, &lt;a href="https://nango.dev/docs/api-integrations/google-calendar" rel="noopener noreferrer"&gt;Google Calendar&lt;/a&gt;, and IMAP, alongside every other API your product will eventually need.&lt;/p&gt;

&lt;p&gt;Nango also ships pre-built Gmail and Google Calendar &lt;a href="https://github.com/NangoHQ/integration-templates" rel="noopener noreferrer"&gt;templates&lt;/a&gt;, so you can start from a working sync or action and customize it, or have your coding agent generate one from scratch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxstj222ohi4oab4muqw9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxstj222ohi4oab4muqw9.gif" alt="Nango supports 800+ APIs across mail, calendar, CRM, messaging, and more" width="760" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that need email and calendar today and will need more integrations (CRM, Storage, Slack, ticketing) tomorrow, and want coding agents to build them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coding agents build the integration:&lt;/strong&gt; install the &lt;a href="https://nango.dev/docs/implementation-guides/platform/functions/leverage-ai-agents" rel="noopener noreferrer"&gt;AI builder skill&lt;/a&gt; and your agent (Claude/Cursor/Gemini) researches the Gmail or Calendar API, writes the sync or action, tests it against a real connection, and iterates until it works.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5v7cg30yn1qsgt1iws8m.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5v7cg30yn1qsgt1iws8m.gif" alt="Claude generating a Gmail action with the Nango AI builder skill" width="600" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent can also build, test, and deploy without a local project, so an agent inside your product can build mail and calendar integrations just-in-time, straight from a customer’s prompt (&lt;a href="https://nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;just-in-time integrations&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full API access:&lt;/strong&gt; you can reach the complete Gmail, Graph, and Calendar APIs, provider-specific fields and endpoints included, and you can still normalize into a &lt;a href="https://nango.dev/blog/build-unified-api-for-product-integrations" rel="noopener noreferrer"&gt;unified API&lt;/a&gt; layer when you want one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You own auth, under your brand:&lt;/strong&gt; a drop-in &lt;a href="https://nango.dev/docs/implementation-guides/platform/auth/implement-api-auth" rel="noopener noreferrer"&gt;Connect UI&lt;/a&gt; handles OAuth, API keys, and token refresh across 800+ APIs. Use your own Google or Microsoft OAuth app so your users authorize you, not Nango.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foeilefo4phmxirk1n3g0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foeilefo4phmxirk1n3g0.gif" alt="Connecting Gmail and sending an email through Nango Connect" width="600" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Durable data syncs and managed webhooks:&lt;/strong&gt; &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/syncs/implement-a-sync" rel="noopener noreferrer"&gt;data syncs&lt;/a&gt; and webhook handling are managed for you, including the Google Calendar channel renewal and resync recovery you would otherwise build by hand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model Context Protocol (&lt;/strong&gt;&lt;a href="https://nango.dev/docs/guides/functions/tool-calling" rel="noopener noreferrer"&gt;&lt;strong&gt;MCP&lt;/strong&gt;&lt;/a&gt;) server and typed tool calls: the AI agents inside your product can send mail or read a calendar through a typed tool call instead of guessing raw parameters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open source and self-hostable:&lt;/strong&gt; integrations live in your repo, the platform is &lt;a href="https://github.com/NangoHQ/nango" rel="noopener noreferrer"&gt;open source&lt;/a&gt;, with &lt;a href="https://trust.nango.dev" rel="noopener noreferrer"&gt;SOC 2 Type II, GDPR, and HIPAA&lt;/a&gt;, with self-hosting for teams that need full data isolation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability:&lt;/strong&gt; every operation produces &lt;a href="https://nango.dev/docs/guides/platform/observability" rel="noopener noreferrer"&gt;structured logs&lt;/a&gt; with full request and response details and OpenTelemetry export.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0w4b3yid6lv2jmmyasrq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0w4b3yid6lv2jmmyasrq.png" alt="Nango observability dashboard with per-request logs" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code-first by design:&lt;/strong&gt; Nango assumes you, or your coding agent, write integration logic as code. Teams that specifically want a non-technical, visual builder for one-off mail and calendar workflows will find a code-first model is more than they need.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Nylas
&lt;/h3&gt;

&lt;p&gt;Nylas is a hosted unified API for email, calendar, and contacts. You write code once against the Nylas API and it works across Gmail, Microsoft 365, Outlook, Exchange, and IMAP. They also added an MCP server in March 2025 and a meeting-notes API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flk0woturs0nvbx9dw5sd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flk0woturs0nvbx9dw5sd.png" alt="The Nylas dashboard with its email, calendar, scheduler, and notetaker products" width="799" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that want a pre-built, hosted email, calendar, and contacts API and do not expect to integrate much beyond communications data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Broad mail and calendar coverage:&lt;/strong&gt; Gmail, Microsoft 365, Outlook, Exchange, and IMAP behind one schema, plus contacts and an embeddable scheduler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mature and hosted:&lt;/strong&gt; webhooks, token refresh, and provider differences are managed for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6bwc13d97qpa7x0t4mj6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6bwc13d97qpa7x0t4mj6.png" alt="Nylas connectors for Google, Microsoft, iCloud, IMAP, and Yahoo" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Communications data only:&lt;/strong&gt; email, calendar, contacts, scheduling, and meeting notes, and nothing else. CRM, Slack, ticketing, or storage require a separate platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Normalized schema is limiting:&lt;/strong&gt; the unified model abstracts away provider-specific fields and behavior, and reviewers report gaps such as not fully supporting certain event types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Breaking API releases:&lt;/strong&gt; Nylas deprecated its v2 API in January 2025 and moved customers to v3, a migration teams describe as significant work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No coding-agent build skill:&lt;/strong&gt; No skill for a coding agent to build, test, and deploy integrations the way Nango’s builder does.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Aurinko
&lt;/h3&gt;

&lt;p&gt;Aurinko is a unified API for email, calendar, contacts, and tasks, positioned as an alternative to Nylas. It runs mainly as a pass-through gateway, so it stores minimal data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxqp6gdlvxfdcy9by4sh9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxqp6gdlvxfdcy9by4sh9.png" alt="The Aurinko dashboard showing mailbox APIs, scheduler, and virtual APIs" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that want a unified mailbox API and do not need coverage beyond email, calendar, contacts, and tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core mailbox coverage:&lt;/strong&gt; Google, Microsoft 365, Exchange, iCloud, and IMAP behind one schema, with webhook subscriptions that auto-renew.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass-through architecture:&lt;/strong&gt; it proxies requests to providers and stores minimal content, which helps in data-sensitive setups.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Communications-only scope:&lt;/strong&gt; email, calendar, contacts, and tasks, plus a configurable CRM-connector layer, but not a broad catalog. You will need another platform for most non-mailbox APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aurinko owns the OAuth app:&lt;/strong&gt; your end users authorize Aurinko, and Aurinko issues its own tokens, so the consent screen and the credentials are not yours.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Facxhz9eau1c3w9y0lql4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Facxhz9eau1c3w9y0lql4.png" alt="Google consent screen showing the user authorizing Aurinko, not your app" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No AI builder or MCP server:&lt;/strong&gt; there is no coding-agent skill and no MCP server, so it is not built for an agent-driven workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Unipile
&lt;/h3&gt;

&lt;p&gt;Unipile is a unified API focused on messaging channels, primarily LinkedIn and WhatsApp, with email and calendar added on. Its main draw is access to social messaging that has no easy official API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ke8t8qzl2990wtqu8aj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ke8t8qzl2990wtqu8aj.png" alt="Unipile's hosted auth wizard for LinkedIn, WhatsApp, Instagram, Telegram, email, and more" width="799" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that specifically need access to personal LinkedIn or WhatsApp accounts that the official APIs do not expose, and accept the account-suspension risk. For official LinkedIn and WhatsApp access, Nango covers those APIs without that risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Messaging breadth:&lt;/strong&gt; LinkedIn, WhatsApp, Instagram, and Telegram in one API, with email (Gmail, Outlook, IMAP) and calendar (Google, Outlook) alongside.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast to connect:&lt;/strong&gt; a hosted auth wizard and an MCP server for agent access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn access is unofficial:&lt;/strong&gt; Unipile states it is not affiliated with LinkedIn and connects through user credentials and sessions. Its own docs warn this can trigger LinkedIn warnings, forced reconnections, and account-suspension risk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communications-only scope:&lt;/strong&gt; messaging, email, and calendar, with no CRM, ticketing, accounting, or storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosted only, tokens on Unipile:&lt;/strong&gt; there is no self-hosting, and the end user authenticates on Unipile’s domain, so credentials live with Unipile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyadjx5seb2crehdrw75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyadjx5seb2crehdrw75.png" alt="Google consent screen showing the user authorizing Unipile" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Calendar is the lighter half:&lt;/strong&gt; the product centers on messaging, and calendar coverage is limited to Google and Outlook.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No coding-agent build skill:&lt;/strong&gt; No skill for a coding agent to build and deploy integrations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to build a mail or calendar integration with Nango
&lt;/h2&gt;

&lt;p&gt;Paste Nango’s &lt;a href="https://nango.dev/docs/getting-started/quickstart#ai-assisted-quickstart" rel="noopener noreferrer"&gt;quickstart&lt;/a&gt; prompt into Claude Code, Cursor, or Codex, and it handles account setup, API keys, and your first connection. To build the integration, install the &lt;a href="https://nango.dev/docs/guides/functions/functions-guide#option-2-build-locally-with-the-cli" rel="noopener noreferrer"&gt;AI builder skill&lt;/a&gt; and describe what you want in plain English.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/building-nango-functions-locally Build a Nango sync for the google-calendar integration
that syncs events from the primary calendar and keeps them current with
webhooks. Then add an action to create an event. Integrate both with the frontend.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent researches the API, writes the sync and action as typed code, runs &lt;code&gt;nango dryrun&lt;/code&gt; against a real connection to test it, and iterates until it works. The integration then runs on Nango’s runtime with managed auth, durable syncs, webhook handling, retries, and logs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmgi3aosyu0u43vkvc0f.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmgi3aosyu0u43vkvc0f.gif" alt="Claude building a Google Calendar integration with the Nango AI builder skill" width="600" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cbqq9fmp9igfz4ixm55.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cbqq9fmp9igfz4ixm55.gif" alt="Real-time Google Calendar sync running in a demo app" width="599" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The workflow is the same for Gmail, Outlook, or Google Calendar and covers any of Nango’s &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;800+ supported APIs&lt;/a&gt;, so the next integration after mail and calendar (a CRM, HRIS, Slack) is built the same way. For end-to-end walkthroughs, see &lt;a href="https://nango.dev/blog/how-to-build-a-gmail-api-integration-with-nango-and-claude" rel="noopener noreferrer"&gt;building a Gmail API integration&lt;/a&gt; and a &lt;a href="https://nango.dev/blog/how-to-build-a-real-time-google-calendar-api-integration" rel="noopener noreferrer"&gt;real-time Google Calendar integration&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side-by-side comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Nango&lt;/th&gt;
&lt;th&gt;Nylas&lt;/th&gt;
&lt;th&gt;Aurinko&lt;/th&gt;
&lt;th&gt;Unipile&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Email (Gmail, Outlook, IMAP)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Calendar (Google, Outlook, iCloud)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Beyond mail and calendar&lt;/td&gt;
&lt;td&gt;800+ APIs&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI integration builder skill&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API access&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Normalized&lt;/td&gt;
&lt;td&gt;Normalized&lt;/td&gt;
&lt;td&gt;Normalized&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You own the OAuth app and tokens&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP server&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open source&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosting&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Choosing the right platform
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;If you need email and calendar now and expect to integrate more (CRM, Slack, ticketing) later, and want coding agents to build it:&lt;/strong&gt; pick Nango.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If you want full API access and to own your users’ auth under your brand:&lt;/strong&gt; pick Nango.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If you only ever need a hosted email, calendar, and contacts API and are comfortable with communications-only scope and tokens on the vendor:&lt;/strong&gt; Nylas fits, or Aurinko for a pass-through alternative.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If you need LinkedIn or WhatsApp alongside email and calendar:&lt;/strong&gt; Nango covers them through their official APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If you want to self-host for data residency:&lt;/strong&gt; Nango supports self-hosting.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is the best Nylas alternative?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nango is the broader alternative, with full API access, your own OAuth app, durable syncs, and an AI builder skill for Claude Code, Cursor, and Codex.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I build a Gmail and Outlook integration with an AI coding agent?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. With Nango, you install the AI builder skill and prompt a coding agent (Claude Code, Cursor, Codex, or others) to build the integration. The agent researches the Gmail or Microsoft Graph API, writes the action or sync as code, tests it against a real connection with &lt;code&gt;nango dryrun&lt;/code&gt;, and iterates until it works. See &lt;a href="https://nango.dev/blog/how-to-build-a-gmail-api-integration-with-nango-and-claude" rel="noopener noreferrer"&gt;building Gmail API integration with Nango and Claude&lt;/a&gt; for an example.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need a unified API for email and calendar?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not always. A unified schema works well when you only read the fields Gmail and Outlook share. It limits you when you need a provider-specific field or endpoint it does not model. A platform with full API access lets you reach the complete provider surface and still normalize into a unified layer when that helps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about Apple iCloud calendars?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;iCloud uses CalDAV (&lt;a href="https://datatracker.ietf.org/doc/html/rfc4791" rel="noopener noreferrer"&gt;RFC 4791&lt;/a&gt;), which has no push notifications, so you sync by polling. The unified mailbox APIs (Nylas, Aurinko) abstract CalDAV for you. With a code-first platform like Nango, you (or your coding agent) build against CalDAV directly when you need iCloud, with the sync infrastructure managed for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I build email and calendar integrations in-house or use a platform?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Based on our experience supporting API integrations across 800+ APIs, we would not recommend building the OAuth, sync, and webhook plumbing from scratch. The provider differences (Gmail’s Pub/Sub &lt;code&gt;watch&lt;/code&gt;, Graph subscription renewal, Calendar &lt;code&gt;syncToken&lt;/code&gt; and &lt;code&gt;410&lt;/code&gt; recovery, CalDAV polling) keep changing, so they cost maintenance time long after the first version ships. A platform handles that layer so your code focuses on your product, and with a code-first platform you keep full control of the integration logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The specialist vendors covered here each solve one slice of the problem. Nylas and Aurinko give you a unified mailbox API, and Unipile leans into social messaging. If mail or calendar is the only integration you will ever build and you fit one of those niches, they work.&lt;/p&gt;

&lt;p&gt;Most products do not stay there. Email and calendar are usually just the first integrations, and a communications-only API means a second vendor once you add a CRM, a help desk, or Slack. Nango covers mail and calendar, and the same platform supports 800+ other integrations, with coding agents doing the building.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/how-to-build-a-gmail-api-integration-with-nango-and-claude" rel="noopener noreferrer"&gt;How to build a Gmail API integration with Nango and Claude&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/how-to-build-a-real-time-google-calendar-api-integration" rel="noopener noreferrer"&gt;How to build a real-time Google Calendar API integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/best-api-integration-platforms-claude-code-cursor-codex" rel="noopener noreferrer"&gt;Best API integration platforms to use with Claude Code, Cursor, and Codex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/why-b2b-saas-outgrow-pre-built-unified-apis" rel="noopener noreferrer"&gt;Why B2B SaaS teams outgrow pre-built unified APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;The emergence of just-in-time integrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/concurrency-with-oauth-token-refreshes" rel="noopener noreferrer"&gt;How to handle concurrency with OAuth token refreshes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nango.dev/blog/google-oauth-invalid-grant-token-has-been-expired-or-revoked" rel="noopener noreferrer"&gt;Google OAuth invalid_grant: what it means and how to fix it&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>integrations</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to sync large amounts of contacts from the HubSpot API</title>
      <dc:creator>Sapnesh Naik</dc:creator>
      <pubDate>Thu, 07 May 2026 16:36:49 +0000</pubDate>
      <link>https://dev.to/nangohq/how-to-sync-large-amounts-of-contacts-from-the-hubspot-api-2acm</link>
      <guid>https://dev.to/nangohq/how-to-sync-large-amounts-of-contacts-from-the-hubspot-api-2acm</guid>
      <description>&lt;p&gt;If you are building API integrations with HubSpot in your product, you will eventually need to sync more than 10,000 contacts from a customer's portal. That is not easy when you want a durable, resumable sync that fetches only new and changed records, instead of refetching everything on every run. You also need to think about managing the auth tokens for 100s of users, record storage, webhook updates, and more.&lt;/p&gt;

&lt;p&gt;This guide walks through how to build a production-ready HubSpot contacts sync using Claude Code, Cursor, Codex, or any other AI Coding Agent with the Nango &lt;a href="https://nango.dev/docs/implementation-guides/platform/functions/leverage-ai-agents" rel="noopener noreferrer"&gt;AI Function Builder&lt;/a&gt; skill.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhslvlwnj4zj8b40ns0z8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhslvlwnj4zj8b40ns0z8.gif" alt="hubspot-contacts-sync-demo-nango" width="560" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The full working demo, including the Nango sync, an Express backend, and an HTML dashboard for browsing synced contacts, is on GitHub at &lt;a href="https://github.com/NangoHQ/blog-demos/tree/main/how-to-sync-large-amounts-of-contacts-from-hubspot-api" rel="noopener noreferrer"&gt;NangoHQ/blog-demos/how-to-sync-large-amounts-of-contacts-from-hubspot-api&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The same steps can also be used for syncing HubSpot companies, deals, tickets, and any other CRM Nango &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;supports&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why syncing large amounts of contacts from HubSpot is hard
&lt;/h2&gt;

&lt;p&gt;HubSpot exposes contacts through two endpoints, and neither one is enough on its own:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Filter by &lt;code&gt;lastmodifieddate&lt;/code&gt;?&lt;/th&gt;
&lt;th&gt;10k total cap?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;GET /crm/v3/objects/contacts&lt;/code&gt; (basic list)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /crm/v3/objects/contacts/search&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (400 error past 10k)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;a href="https://developers.hubspot.com/docs/api-reference/latest/crm/search-the-crm#limits" rel="noopener noreferrer"&gt;search-the-crm guide&lt;/a&gt; confirms it: &lt;em&gt;"The search endpoints are limited to 10,000 total results for any given query. Attempting to page beyond 10,000 will result in a 400 error."&lt;/em&gt; Search is also rate-limited to five requests per second per account.&lt;/p&gt;

&lt;p&gt;So the search endpoint is the only one that filters by &lt;code&gt;lastmodifieddate&lt;/code&gt; (what you need for incremental syncs), but it walls off at 10k. The basic list endpoint has no cap but no filter. The HubSpot community forum is full of &lt;a href="https://community.hubspot.com/t5/APIs-Integrations/Contact-Search-API-400-Bad-Request-when-fetching-records-after/m-p/446340" rel="noopener noreferrer"&gt;400 reports from developers&lt;/a&gt; who only used search and assumed their code was broken.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution to sync large amounts of contacts from HubSpot
&lt;/h2&gt;

&lt;p&gt;Split the sync into two phases that share state via &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/syncs/checkpoints" rel="noopener noreferrer"&gt;Nango checkpoints&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Initial phase.&lt;/strong&gt; Page through every contact using the basic list endpoint. No 10k cap. After each page, save a checkpoint with the &lt;code&gt;after&lt;/code&gt; cursor and the highest &lt;code&gt;lastmodifieddate&lt;/code&gt; seen so far.
&lt;strong&gt;Note:&lt;/strong&gt; while this endpoint does have &lt;code&gt;lastmodifieddate&lt;/code&gt; in its response, it does not support filtering by &lt;code&gt;lastmodifieddate&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incremental phase.&lt;/strong&gt; Switch to the search endpoint. Filter by &lt;code&gt;lastmodifieddate GT &amp;lt;watermark&amp;gt;&lt;/code&gt;, sort ascending by &lt;code&gt;lastmodifieddate&lt;/code&gt;, and page through. Each page advances the watermark. If a request 400s past the 10k cap, catch the error, save the latest watermark, and start a fresh search from it inside the same run. Repeat until a search returns fewer than 10k results, so no modified records are missed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why building this from scratch is harder than it looks
&lt;/h2&gt;

&lt;p&gt;The two-phase pattern is the easy part. The infrastructure underneath is the hard part:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Durable checkpoints&lt;/strong&gt; that survive process restarts and store per-connection cursors and watermarks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resumable execution,&lt;/strong&gt; so a 200k-contact backfill can stop and pick up across multiple runs without skipping or duplicating records.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HubSpot OAuth lifecycle&lt;/strong&gt; with &lt;a href="https://www.nango.dev/blog/concurrency-with-oauth-token-refreshes" rel="noopener noreferrer"&gt;concurrent token refreshes&lt;/a&gt; and graceful handling of &lt;a href="https://www.nango.dev/blog/hubspot-oauth-bad-refresh-token" rel="noopener noreferrer"&gt;&lt;code&gt;BAD_REFRESH_TOKEN&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate-limit handling&lt;/strong&gt; with backoff and per-connection queuing for HubSpot's 5 req/s search cap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sync-completion webhooks&lt;/strong&gt; so your backend knows when new records landed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Nango provides for building API integrations
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.nango.dev/" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; is an agentic API integrations platform. It gives you five building blocks that turn the two-phase pattern from a multi-week project into minutes of work with a coding agent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Wide API support with managed auth.&lt;/strong&gt; Pre-built auth for &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;700+ APIs,&lt;/a&gt; including HubSpot, with OAuth 2.0, API keys, basic auth, JWT, and other auth types. Token refresh, encryption, and revocation handling are managed for you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://nango.dev/docs/implementation-guides/platform/functions/leverage-ai-agents" rel="noopener noreferrer"&gt;AI Function Builder&lt;/a&gt; skill for coding agents.&lt;/strong&gt; Install once with &lt;code&gt;npx skills add NangoHQ/skills&lt;/code&gt; and your AI coding agent (Claude Code, Cursor, Codex, Gemini CLI, and others) gets the context to research the API, write a Nango sync or action in TypeScript, run dryruns against a real connection, and iterate until the integration works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actions and tool calls.&lt;/strong&gt; Actions are functions written in TypeScript that run on Nango's infrastructure and are triggered from your app or by an AI agent. For example, a &lt;code&gt;create-contact&lt;/code&gt; action calls &lt;code&gt;POST /crm/v3/objects/contacts&lt;/code&gt; with the right token for the right connection, returning the created record.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data syncs with record storage.&lt;/strong&gt; Syncs run on Nango's serverless, tenant-isolated runtime. Synced records are stored in Nango's cache so your app can read them in a paginated manner with &lt;code&gt;nango.listRecords()&lt;/code&gt;. The sync handles retries, rate limits, and resumable execution automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhooks from external APIs.&lt;/strong&gt; Nango ingests webhooks from external providers like HubSpot (for example, &lt;code&gt;contact.deletion&lt;/code&gt; events), attributes each event to the right connection, and forwards a normalized payload to your backend. You write the handler once and Nango deals with provider-specific signing, retries, and routing.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Implementing a HubSpot contacts sync with Nango
&lt;/h2&gt;

&lt;p&gt;Follow the steps below to implement a durable HubSpot contacts sync using the Nango AI Function Builder skill.&lt;/p&gt;

&lt;p&gt;By the end of this section, you will have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A customizable &lt;a href="https://nango.dev/docs/implementation-guides/platform/auth/implement-api-auth" rel="noopener noreferrer"&gt;auth UI&lt;/a&gt; in your product so customers can connect their HubSpot account.&lt;/li&gt;
&lt;li&gt;An initial backfill sync that fires the moment a new HubSpot connection is created and pulls all contacts.&lt;/li&gt;
&lt;li&gt;An incremental phase that picks up only modified contacts on every run (every hour, customizable) and slides past the 10k search cap automatically.&lt;/li&gt;
&lt;li&gt;Checkpoints that survive runtime restarts and rate limits.&lt;/li&gt;
&lt;li&gt;A backend that receives sync-completion webhooks and reads only the records that changed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;You will need a &lt;a href="https://nango.dev/" rel="noopener noreferrer"&gt;Nango account&lt;/a&gt; (the free tier is enough for development). Then &lt;a href="https://nango.dev/docs/api-integrations/hubspot#hubspot" rel="noopener noreferrer"&gt;register your own HubSpot OAuth app&lt;/a&gt; with the &lt;code&gt;crm.objects.contacts.read&lt;/code&gt; scope, set the OAuth callback URL to &lt;code&gt;https://api.nango.dev/oauth/callback&lt;/code&gt;, and &lt;a href="https://app.nango.dev/dev/integrations" rel="noopener noreferrer"&gt;configure HubSpot as an integration&lt;/a&gt; in the Nango dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xstefvk3hs2dq60pg41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xstefvk3hs2dq60pg41.png" alt="Nango dashboard with HubSpot configured as an integration: client ID, client secret, callback URL, and the crm.objects.contacts.read scope" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you do not have your own HubSpot OAuth app yet, you can use Nango's pre-configured developer credentials to get going, then swap to your own credentials before going to production.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fer86uoxlr7fw20fuln9b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fer86uoxlr7fw20fuln9b.jpg" alt="Nango dashboard offering pre-configured HubSpot developer credentials for a quick start" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, install the &lt;a href="https://nango.dev/docs/reference/cli" rel="noopener noreferrer"&gt;Nango CLI&lt;/a&gt; and initialize an integrations project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; nango
nango init
&lt;span class="nb"&gt;cd &lt;/span&gt;nango-integrations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then install the &lt;a href="https://nango.dev/docs/implementation-guides/platform/functions/leverage-ai-agents#install-the-nango-function-builder-skill" rel="noopener noreferrer"&gt;AI Function Builder skill&lt;/a&gt;, so your coding agent has the context it needs to write Nango functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add NangoHQ/skills &lt;span class="nt"&gt;-s&lt;/span&gt; building-nango-functions-locally
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This adds Nango's interface patterns, Zod schema conventions, dryrun testing flow, and CLI usage to whichever coding agent you use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; LLM training data on Nango is often stale. Add the &lt;a href="https://nango.dev/docs/mcp" rel="noopener noreferrer"&gt;Nango docs MCP server&lt;/a&gt; alongside the skill, so your agent can pull current API references during code generation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdvjnslrlxuew8zny9t8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdvjnslrlxuew8zny9t8.gif" alt="Installing the Nango AI skill in Claude Code" width="560" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, set a Nango dev API key in a &lt;code&gt;.env&lt;/code&gt; file at the root of &lt;code&gt;nango-integrations&lt;/code&gt; so the CLI and dryrun commands can authenticate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# nango-integrations/.env&lt;/span&gt;
&lt;span class="nv"&gt;NANGO_SECRET_KEY_DEV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your-dev-api-key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can create or copy a dev API key from the &lt;a href="https://app.nango.dev/dev/environment-settings" rel="noopener noreferrer"&gt;Nango dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Add a HubSpot test connection
&lt;/h3&gt;

&lt;p&gt;Before generating the sync, create a real HubSpot connection in the Nango dashboard. The AI coding agent uses this connection to run &lt;code&gt;nango dryrun&lt;/code&gt; against the live HubSpot API while it iterates on the function, so the generated code is tested against real responses.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://app.nango.dev/dev/connections" rel="noopener noreferrer"&gt;Nango dashboard&lt;/a&gt;, click &lt;strong&gt;Add Test Connection&lt;/strong&gt;, pick HubSpot, and complete the OAuth flow against a HubSpot developer account. Copy the connection ID from the connection details page; you will pass it into the prompt in the next step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxou4u3k1moderkpjqqr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxou4u3k1moderkpjqqr.gif" alt="Adding a HubSpot test connection from the Nango dashboard via the OAuth flow" width="600" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Generate the contacts sync
&lt;/h3&gt;

&lt;p&gt;Open your project in your AI coding agent and invoke the AI Function Builder skill with a prompt like the one below. Replace the connection ID with the one you just created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Build a Nango sync for HubSpot contacts that runs every hour, handles
portals with more than 10,000 contacts reliably, and resumes cleanly
across runs without skipping or duplicating records.

Integration ID: hubspot
Connection ID: &lt;span class="nt"&gt;&amp;lt;your-connection-id&amp;gt;&lt;/span&gt;

Properties to sync: firstname, lastname, email, phone, jobtitle,
company, createdate, lastmodifieddate.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent figures out the rest from HubSpot's docs and the AI Function Builder skill: which endpoints to use, how to paginate, how to handle the 10k search cap, and how to checkpoint for resumability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6nxgtii62k355e7bpbx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6nxgtii62k355e7bpbx.gif" alt="Claude Code generating the HubSpot contacts sync function via the Nango AI Function Builder skill" width="600" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agent researches both endpoints, writes the function, generates a test suite, runs &lt;code&gt;nango dryrun&lt;/code&gt; against your test connection, and iterates on real responses until everything passes. &lt;a href="https://nango.dev/docs/guides/functions/functions-guide#function-ai-builder" rel="noopener noreferrer"&gt;Here is what the agent does behind the scenes&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Review the generated sync
&lt;/h3&gt;

&lt;p&gt;When the agent finishes, you will see three new files inside &lt;code&gt;nango-integrations/hubspot/&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/NangoHQ/blog-demos/blob/main/how-to-sync-large-amounts-of-contacts-from-hubspot-api/nango-integrations/hubspot/syncs/fetch-contacts.ts" rel="noopener noreferrer"&gt;&lt;code&gt;hubspot/syncs/fetch-contacts.ts&lt;/code&gt;&lt;/a&gt;: the sync function itself, with the two-phase logic, checkpoint schema, and Zod model.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hubspot/tests/fetch-contacts.test.json&lt;/code&gt;: a recorded HubSpot API response captured during the agent's dryrun, used as a deterministic fixture for unit tests.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hubspot/tests/hubspot-fetch-contacts.test.ts&lt;/code&gt;: the unit test that replays the fixture and asserts the sync produces the expected records.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's look at the important bits of the sync file. The full file with imports, schemas, helpers, and types is in &lt;a href="https://github.com/NangoHQ/blog-demos/blob/main/how-to-sync-large-amounts-of-contacts-from-hubspot-api/nango-integrations/hubspot/syncs/fetch-contacts.ts" rel="noopener noreferrer"&gt;the demo repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The &lt;code&gt;createSync&lt;/code&gt; declaration and phase dispatcher.&lt;/strong&gt; A string-only &lt;code&gt;CheckpointSchema&lt;/code&gt; carries the phase, the basic-list cursor, and the watermark across runs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CheckpointSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;phase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;lastmodifieddate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sync&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Two-phase HubSpot contacts sync that slides past the 10k search cap.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;every hour&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;autoStart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;checkpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CheckpointSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;HubspotContact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HubspotContactSchema&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCheckpoint&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;phase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;checkpoint&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;phase&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incremental&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incremental&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;initial&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;watermark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;checkpoint&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;lastmodifieddate&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phase&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;initial&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;watermark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;runInitialPhase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;checkpoint&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;after&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;runIncrementalPhase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Initial phase: paginate through the basic list endpoint, save a checkpoint per page.&lt;/strong&gt; No 10k cap on this endpoint, so a 200k-contact portal flows through across however many runs are needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proxyConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/crm/v3/objects/contacts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PAGE_LIMIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PROPERTIES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cursor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;cursor_name_in_request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;after&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;cursor_path_in_response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;paging.next.after&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;response_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;results&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PAGE_LIMIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;on_page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;nextPageParam&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;nextPageParam&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;nextPageParam&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;saveCheckpoint&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;phase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;initial&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;nextPageParam&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastmodifieddate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;watermark&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Backfill done. Switch to incremental on the next run.&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;saveCheckpoint&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;phase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incremental&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastmodifieddate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;watermark&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paginate&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HubspotContactRaw&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyConfig&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contacts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toContact&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;batchSave&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HubspotContact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;watermark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;highestWatermark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Incremental phase: search filtered by watermark, ascending, checkpointed per page.&lt;/strong&gt; This is the part that solves the 10k cap. &lt;code&gt;filterWatermark&lt;/code&gt; defines the search; &lt;code&gt;savedWatermark&lt;/code&gt; advances per page. When a paged request 400s past the 10k cap, catch the error, restart the search from the latest watermark, and continue inside the same run until a slice returns fewer than 10k results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;filterWatermark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;savedWatermark&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterGroups&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lastmodifieddate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;toMillisecondsString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filterWatermark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// HubSpot wants Unix milliseconds&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;}];&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hitTenKCap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SearchResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/crm/v3/objects/contacts/search&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;filterGroups&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;sorts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lastmodifieddate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ASCENDING&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
                    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;PROPERTIES&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                    &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PAGE_LIMIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;after&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Past the 10k cap, HubSpot returns a 400. Restart the search&lt;/span&gt;
            &lt;span class="c1"&gt;// from the latest watermark inside the same run.&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isTenKCapError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;hitTenKCap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contacts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toContact&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;batchSave&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HubspotContact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;savedWatermark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;highestWatermark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;savedWatermark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;saveCheckpoint&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;phase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incremental&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastmodifieddate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;savedWatermark&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;after&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paging&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;after&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;after&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hitTenKCap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;filterWatermark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;savedWatermark&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Slide the search window forward and loop.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few design decisions worth calling out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Checkpoints saved per page.&lt;/strong&gt; The initial phase uses &lt;code&gt;nango.paginate&lt;/code&gt; with an &lt;code&gt;on_page&lt;/code&gt; callback; the incremental phase saves inline after each &lt;code&gt;batchSave&lt;/code&gt;. Either way, if the function is interrupted, the next run resumes from the saved state rather than starting over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ascending sort on &lt;code&gt;lastmodifieddate&lt;/code&gt;.&lt;/strong&gt; Each search returns the lowest-watermark records first. When a request 400s past the 10k cap, the latest saved watermark is already past everything we just processed, so restarting the search from it picks up the next slice without gaps. The outer loop keeps sliding the window forward until a slice fits under 10k.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Milliseconds, not ISO, for the search filter.&lt;/strong&gt; HubSpot's search endpoint expects &lt;code&gt;lastmodifieddate&lt;/code&gt; as Unix milliseconds. &lt;code&gt;toMillisecondsString&lt;/code&gt; handles the conversion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Deploy
&lt;/h3&gt;

&lt;p&gt;Deploy just this sync to your Nango dev environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nango deploy &lt;span class="nt"&gt;--sync&lt;/span&gt; fetch-contacts dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4e2k62qm0nt40s2b6ybm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4e2k62qm0nt40s2b6ybm.jpg" alt="Nango CLI terminal output after deploying the fetch-contacts sync to the dev environment" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The sync now runs every hour for every connected HubSpot portal, starting with the initial backfill and automatically transitioning to the incremental phase once the backfill catches up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Handle sync-completion webhooks in your backend
&lt;/h3&gt;

&lt;p&gt;When a sync run finishes with new records, Nango sends a &lt;a href="https://nango.dev/docs/implementation-guides/platform/webhooks-from-nango#overview-of-nango-webhooks" rel="noopener noreferrer"&gt;sync-completion webhook&lt;/a&gt; to your backend with counts of added, updated, and deleted records, plus a &lt;code&gt;modifiedAfter&lt;/code&gt; timestamp. Set the webhook URL in the Nango dashboard under &lt;strong&gt;Environment Settings &amp;gt; Webhooks&lt;/strong&gt;. The &lt;a href="https://github.com/NangoHQ/blog-demos/tree/main/how-to-sync-large-amounts-of-contacts-from-hubspot-api/demo-app" rel="noopener noreferrer"&gt;demo app&lt;/a&gt; shows a working Express backend and an HTML dashboard that displays the synced contacts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55590tjl3l9e2d39nm2g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55590tjl3l9e2d39nm2g.jpg" alt="Setting the sync-completion webhook URL in Nango Environment Settings" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then fetch only the records that changed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nango&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listRecords&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;providerConfigKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hubspot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;connectionId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HubspotContact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;modifiedAfter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;webhookPayload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modifiedAfter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Always &lt;a href="https://nango.dev/docs/implementation-guides/platform/webhooks-from-nango#verifying-webhooks-from-nango" rel="noopener noreferrer"&gt;verify the webhook signature&lt;/a&gt; before processing using &lt;code&gt;nango.verifyIncomingWebhookRequest()&lt;/code&gt;. Nango signs payloads with HMAC-SHA256, and verification requires the raw request body (before JSON parsing).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nango.listRecords&lt;/code&gt; is paginated. Loop through &lt;code&gt;next_cursor&lt;/code&gt; until it returns null, so you do not silently drop records on portals with very high modification rates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local testing tip:&lt;/strong&gt; To inspect webhooks during development, run &lt;a href="https://ngrok.com/" rel="noopener noreferrer"&gt;ngrok&lt;/a&gt; against your local backend and set the ngrok URL as the webhook target in Nango's environment settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcak22w24fi2ja744m6wi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcak22w24fi2ja744m6wi.jpg" alt="Pasting the ngrok URL as the webhook target in Nango environment settings for local development" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Connect a new HubSpot account and test
&lt;/h3&gt;

&lt;p&gt;With the sync deployed, connect a new HubSpot portal through Nango's &lt;a href="https://nango.dev/docs/implementation-guides/platform/auth/implement-api-auth" rel="noopener noreferrer"&gt;auth UI&lt;/a&gt;. The sync starts immediately because of &lt;code&gt;autoStart: true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfedmaz1peeqvw8063om.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfedmaz1peeqvw8063om.gif" alt="nango-live-sync" width="600" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To verify the sync is doing the right thing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Check the dashboard.&lt;/strong&gt; The Nango dashboard shows per-run logs, record counts, current checkpoint, and durations. You should see an initial-phase run that each process all the contacts, then incremental runs that process only modified contacts.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1b8zknhf4g7n7vz7v1q1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1b8zknhf4g7n7vz7v1q1.jpg" alt="Nango sync logs" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Watch the checkpoint.&lt;/strong&gt; During the initial phase, the checkpoint shows &lt;code&gt;phase: "initial"&lt;/code&gt; with an advancing &lt;code&gt;after&lt;/code&gt; cursor. Once the backfill completes, the phase flips to &lt;code&gt;"incremental"&lt;/code&gt; and the &lt;code&gt;lastmodifieddate&lt;/code&gt; watermark starts moving forward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modify a contact in HubSpot.&lt;/strong&gt; Within the next hour, the incremental sync should pick it up, and your backend should receive a sync-completion webhook with &lt;code&gt;addedOrUpdated: 1&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Edge cases worth knowing about
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom properties.&lt;/strong&gt; Update the prompt with the custom property names and rerun the AI Function Builder skill. For per-customer property lists, store them in &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/customer-configuration" rel="noopener noreferrer"&gt;connection metadata&lt;/a&gt; and read them during the sync.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deletes.&lt;/strong&gt; Search does not return deleted contacts. Subscribe to HubSpot's &lt;code&gt;contact.deletion&lt;/code&gt; &lt;a href="https://developers.hubspot.com/docs/guides/api/app-management/webhooks" rel="noopener noreferrer"&gt;webhook&lt;/a&gt;. Nango can &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/webhooks-from-external-apis" rel="noopener noreferrer"&gt;forward those webhooks&lt;/a&gt; to your backend after attributing each event to the right connection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Syncing large amounts of contacts from HubSpot requires both of HubSpot's contact endpoints. Search filters by &lt;code&gt;lastmodifieddate&lt;/code&gt; but caps at 10,000 results. The basic list endpoint has no cap but cannot filter. A reliable sync uses both, with checkpoints that resume cleanly across runs and durable infrastructure underneath: OAuth refresh, retries, rate limit handling, and webhook routing.&lt;/p&gt;

&lt;p&gt;With Nango, the sync logic is a code function your AI coding agent generates from a prompt, while the infrastructure is managed for you. The same approach works for HubSpot companies, deals, tickets, and any of Nango's &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;700+ supported APIs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/hubspot-api-integration" rel="noopener noreferrer"&gt;Step by step guide to building a native HubSpot API integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/hubspot-oauth-bad-refresh-token" rel="noopener noreferrer"&gt;HubSpot OAuth BAD_REFRESH_TOKEN: what it means and how to fix it&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/how-to-build-a-real-time-google-calendar-api-integration" rel="noopener noreferrer"&gt;How to build a real-time Google Calendar API integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/concurrency-with-oauth-token-refreshes" rel="noopener noreferrer"&gt;How to handle concurrency with OAuth token refreshes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/nango-api-integrations-builder-skill" rel="noopener noreferrer"&gt;Introducing the Nango API integrations builder skill&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hubspot</category>
      <category>api</category>
      <category>claude</category>
      <category>agents</category>
    </item>
    <item>
      <title>Best agentic API integrations platform in 2026</title>
      <dc:creator>Sapnesh Naik</dc:creator>
      <pubDate>Fri, 24 Apr 2026 10:26:14 +0000</pubDate>
      <link>https://dev.to/nangohq/best-agentic-api-integrations-platform-in-2026-4ol2</link>
      <guid>https://dev.to/nangohq/best-agentic-api-integrations-platform-in-2026-4ol2</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;An agentic API integrations platform is where coding agents (like Claude, Cursor) build API integrations and AI agents in your product call them at runtime. The platform gives you three things in one stack: integrations-as-code (prompted by you and written by your coding agent), a secure, scalable runtime, and Managed Auth for external APIs with data sync. It is the successor to embedded iPaaS (2010s, low-code) and closed unified APIs (early 2020s, narrow scope). &lt;/p&gt;

&lt;p&gt;An agentic API integrations platform also enables you to set up &lt;a href="https://nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;just-in-time integrations&lt;/a&gt;, where integrations are generated on demand using an AI coding agent and consumed by other AI agents in production.&lt;/p&gt;

&lt;p&gt;Three platforms worth evaluating in 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nango:&lt;/strong&gt; An agentic API integrations platform supporting 700+ APIs. Coding agents build integrations with the Nango AI builder skill, running against a secure and scalable runtime. AI agents consume those integrations through an MCP server, tool calls, webhooks, and data syncs. Open-source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arcade:&lt;/strong&gt; An MCP-first runtime for agent tool calling with permission checks and evaluation testing. Catalog of 112 first-party integrations, focused on the run side only. Not fully agentic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composio:&lt;/strong&gt; A closed-source tool library for agent integrations across 500+ apps. No code-level customization, no data syncs or webhooks, limited observability. Not fully agentic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Agentic API integrations: A new platform category
&lt;/h2&gt;

&lt;p&gt;For more than a decade, teams built product integrations by hand. Read the API docs, implement OAuth, handle pagination, write error handling, test, ship, and maintain. A typical team shipped 3 to 5 integrations per quarter. However, customers now ask for integrations with hundreds of tools. Engineering cannot pre-build every use case one at a time.&lt;/p&gt;

&lt;p&gt;Two things changed since October 2025:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AI coding agents can build integrations autonomously:&lt;/strong&gt; Claude Code, Cursor, Codex, and Gemini CLI can read API docs, iterate on a failing request, and produce a working integration. We &lt;a href="https://www.nango.dev/blog/learned-building-200-api-integrations-with-opencode" rel="noopener noreferrer"&gt;built 200+ integrations in 15 minutes&lt;/a&gt; using OpenCode and the &lt;a href="https://nango.dev/docs/implementation-guides/platform/functions/leverage-ai-agents" rel="noopener noreferrer"&gt;Nango builder skill&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every AI agent needs API access at runtime:&lt;/strong&gt; Agents need to read context from external systems to understand the task and take action to complete it. Common examples include fetching a customer record from the CRM, sending a Slack message, drafting an email in Gmail, or updating a ticket in Linear.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These two shifts collapse into the same use case. The agent that uses the integration is increasingly likely to ask another agent to build what it needs. This is the idea behind &lt;a href="https://www.nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;just-in-time integrations&lt;/a&gt;: integrations generated on demand, prompted by an engineer, another agent, or an end customer, rather than pre-built by the platform for every use case. Instead of handcrafting each integration, teams build an integration factory. The more the coding agent does, the less human involvement is needed.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpp2r7s06k5o1kkosaa2n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpp2r7s06k5o1kkosaa2n.jpg" alt="Agentic API integrations platform: the Build, Run, and Maintain loops" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an agentic API integrations platform?
&lt;/h2&gt;

&lt;p&gt;An agentic API integrations platform lets engineers and coding agents build, run, and maintain integrations at scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. AI coding agents build integrations:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The platform exposes skills, SDKs, and a testing loop (test runs against real APIs, real credentials, real logs) so a coding agent (like Claude, Cursor, Codex) can author, test, and deploy integrations end to end. Integrations are code in your repo, so your team keeps full version control, review, and audit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. AI agents in production consume integrations:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The platform exposes the same integrations as typed tool calls, MCP servers, data syncs, and webhook triggers, so product-facing agents can reliably act on external systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Developers stay in control:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The integration is code that your engineers can read, review, and edit. Coding agents can write integrations end-to-end, or a human engineer can drive a coding agent with review on every change. The platform supports both modes, so teams move fast without losing control of what ships.&lt;/p&gt;

&lt;p&gt;As you can see, the word "agentic" has two implications. On the build side, agents produce the integration code. On the run side, agents consume the integration at runtime. An agentic API integrations platform supports both.&lt;/p&gt;

&lt;p&gt;Supporting both the run and the build side matters because platforms that do only one side of the job hit a wall quickly. A tool library without a build workflow cannot quickly scale API integrations, customize integrations for specific customers, or react to schema changes in the external API. A coding assistant without a runtime cannot ship anything to production.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agentic API integrations platform vs. earlier categories
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Era&lt;/th&gt;
&lt;th&gt;Builder&lt;/th&gt;
&lt;th&gt;Consumer&lt;/th&gt;
&lt;th&gt;Limitations&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Embedded iPaaS&lt;/td&gt;
&lt;td&gt;2010s&lt;/td&gt;
&lt;td&gt;Human in a low-code editor&lt;/td&gt;
&lt;td&gt;Human end user&lt;/td&gt;
&lt;td&gt;Visual builders, AI coding agents cannot build using the platform, nor can AI agents consume integrations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unified API&lt;/td&gt;
&lt;td&gt;Early 2020s&lt;/td&gt;
&lt;td&gt;Platform vendor (fixed catalog)&lt;/td&gt;
&lt;td&gt;Backend engineers&lt;/td&gt;
&lt;td&gt;Constrained schemas, limited categories covered, no customization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agentic API integrations platform&lt;/td&gt;
&lt;td&gt;2026+&lt;/td&gt;
&lt;td&gt;AI coding agent or backend engineer in your repo&lt;/td&gt;
&lt;td&gt;AI agent in your product, or your SaaS&lt;/td&gt;
&lt;td&gt;Emerging category&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For deeper context on the older categories, see &lt;a href="https://www.nango.dev/blog/how-is-nango-different-from-embedded-ipaas-or-unified-api" rel="noopener noreferrer"&gt;how Nango differs from embedded iPaaS and unified APIs&lt;/a&gt;, &lt;a href="https://www.nango.dev/blog/what-is-an-embedded-ipaas" rel="noopener noreferrer"&gt;what is an embedded iPaaS&lt;/a&gt;, and &lt;a href="https://www.nango.dev/blog/what-is-a-unified-api" rel="noopener noreferrer"&gt;what is a unified API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to look for in an agentic integrations platform
&lt;/h2&gt;

&lt;p&gt;Evaluate a platform against the build side, the run side, and the runtime that connects them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build side: Can AI coding agents build integrations on it?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A dedicated skill or SDK that encodes integration patterns (auth, pagination, delete detection, checkpoints, error handling) so the agent does not start from a blank file.&lt;/li&gt;
&lt;li&gt;Compatibility with the coding agents your team already uses: Claude Code, Cursor, Codex, Gemini CLI, GitHub Copilot, OpenCode.&lt;/li&gt;
&lt;li&gt;A testing command that executes generated code against a real connection and surfaces real API responses, so the agent can iterate on actual errors instead of hallucinating.&lt;/li&gt;
&lt;li&gt;Deployment through CI/CD with version control, unlimited environments, and no vendor-specific build pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Run side: Can AI agents consume integrations at runtime?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A built-in MCP server so agents speak a standard protocol.&lt;/li&gt;
&lt;li&gt;Typed tool calls with strict input and output schemas so the LLM does not guess parameters.&lt;/li&gt;
&lt;li&gt;Real-time triggers (webhooks, polling) so agents react to provider events, not just initiate requests.&lt;/li&gt;
&lt;li&gt;Data syncs to enhance the context of your agent (for example, RAG) and keep data fresh across millions of records.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Runtime and security:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Managed authentication across OAuth, API keys, JWT, basic auth, and &lt;a href="https://nango.dev/docs/updates/product#support-for-mcp-auth" rel="noopener noreferrer"&gt;MCP Auth&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A white-label, drop-in auth UI so end users authorize under your brand, not the platform's.&lt;/li&gt;
&lt;li&gt;Tenant isolation and per-customer resource limits, since one customer's integration should never affect another's.&lt;/li&gt;
&lt;li&gt;Deep, real-time observability: full request and response logs, custom log messages, and OpenTelemetry export. Both agents and humans need to read failures.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nango.dev/docs/implementation-guides/use-cases/customer-configuration" rel="noopener noreferrer"&gt;Per-customer configuration&lt;/a&gt; for custom field mappings and tenant-specific behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use this checklist when evaluating any platform in the category.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best agentic API integrations platforms
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Nango
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.nango.dev" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; is an &lt;a href="https://github.com/NangoHQ/nango" rel="noopener noreferrer"&gt;open-source&lt;/a&gt; agentic API integrations platform. Coding agents can build and maintain integrations on it using the &lt;a href="https://nango.dev/docs/implementation-guides/platform/functions/leverage-ai-agents" rel="noopener noreferrer"&gt;Nango AI builder skill&lt;/a&gt;. AI agents inside your product call those integrations at runtime through an MCP server, tool calls, webhooks, and data syncs.&lt;/p&gt;

&lt;p&gt;Nango supports &lt;a href="https://nango.dev/api-integrations" rel="noopener noreferrer"&gt;700+ APIs&lt;/a&gt; out of the box and is used as core infrastructure by &lt;a href="https://www.nango.dev/customers" rel="noopener noreferrer"&gt;hundreds of fast-growing AI companies&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxstj222ohi4oab4muqw9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxstj222ohi4oab4muqw9.gif" alt="NangoAPIsNew" width="720" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams building production AI agents that want coding agents to generate integrations on demand, with a secure and scalable runtime to execute them. Includes runtime primitives (MCP, tool calls, syncs, webhooks) to expose those integrations to the AI agents inside a SaaS product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI builder skill for 18+ coding agents:&lt;/strong&gt; Install with one command, and the skill gives Claude Code, Cursor, Codex, Gemini CLI, OpenCode, and others the context to research an API, write the integration, test it against a real connection, and iterate on real errors. See the walkthrough of &lt;a href="https://www.nango.dev/blog/how-to-build-a-real-time-google-calendar-api-integration" rel="noopener noreferrer"&gt;building a real-time Google Calendar API integration&lt;/a&gt; end-to-end with the Nango AI builder skill.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="c"&gt;# Install the Nango skills for your coding agent&lt;/span&gt;
  npx skills add NangoHQ/skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;  &lt;span class="c"&gt;&amp;lt;!-- Sample prompt --&amp;gt;&lt;/span&gt;

  Build a Nango sync that fetches events from the primary Google Calendar.

  Should run hourly, backfill on initial sync for the last 30 days and
  all future events. After the first run, only fetch future events
  incrementally.

  Return at least:
&lt;span class="p"&gt;  -&lt;/span&gt; Event title
&lt;span class="p"&gt;  -&lt;/span&gt; Start and end date
&lt;span class="p"&gt;  -&lt;/span&gt; Location
&lt;span class="p"&gt;  -&lt;/span&gt; RSVP status
&lt;span class="p"&gt;  -&lt;/span&gt; Attendees list (email, display name, response status)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgwagsz736q2xu8i9q91.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgwagsz736q2xu8i9q91.gif" alt="Claude Code building a Google Calendar sync using the Nango AI builder skill" width="560" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test generated code against real APIs:&lt;/strong&gt; AI coding agents use the &lt;a href="https://nango.dev/docs/reference/cli" rel="noopener noreferrer"&gt;Nango CLI&lt;/a&gt;, which includes a &lt;code&gt;dryrun&lt;/code&gt; command that executes generated code against a real connection, returns real responses, and lets the agent iterate until tests pass. This closes the loop that most coding agents lack when building integrations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built-in MCP server and typed tool calls:&lt;/strong&gt; Nango exposes every action as a typed, deterministic &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/tool-calling/overview" rel="noopener noreferrer"&gt;tool call&lt;/a&gt; through a REST API or &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/tool-calling/implement-mcp-server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;. Agents see clear input and output schemas, reducing the risk of hallucinations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Beyond tool calls on the same platform:&lt;/strong&gt; Native &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/syncs/implement-a-sync" rel="noopener noreferrer"&gt;data syncs for RAG&lt;/a&gt;, &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/webhooks-from-external-apis" rel="noopener noreferrer"&gt;webhook processing&lt;/a&gt;, polling triggers, &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/customer-configuration" rel="noopener noreferrer"&gt;per-customer configuration&lt;/a&gt;, and an extensible &lt;a href="https://www.nango.dev/blog/build-unified-api-for-product-integrations" rel="noopener noreferrer"&gt;unified API layer&lt;/a&gt;. Your agent can read context, react to events, and take actions all within the same platform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;White-label auth across 700+ APIs:&lt;/strong&gt; A &lt;a href="https://nango.dev/docs/implementation-guides/platform/auth/implement-api-auth" rel="noopener noreferrer"&gt;drop-in UI component&lt;/a&gt; handles OAuth, API keys, JWT, basic auth, and MCP Auth. Custom credential validation and token refresh are built in. Your end users authorize under your brand.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9u89rt6u2jojrtvxmdhz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9u89rt6u2jojrtvxmdhz.gif" alt="ConnectUICustom" width="600" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Low-overhead, tenant-isolated runtime:&lt;/strong&gt; Tool calls add less than 100ms of overhead. The &lt;a href="https://nango.dev/docs/updates/product#serverless-runtime-for-execution" rel="noopener noreferrer"&gt;serverless execution runtime&lt;/a&gt; automatically scales during traffic surges and isolates each customer. Syncs use &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/syncs/checkpoints" rel="noopener noreferrer"&gt;durable checkpoints&lt;/a&gt; to resume across millions of records.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Real-time observability with OpenTelemetry:&lt;/strong&gt; Every operation generates &lt;a href="https://nango.dev/docs/guides/platform/observability" rel="noopener noreferrer"&gt;structured logs&lt;/a&gt; with full request and response details. Custom log messages, full-text search, and export through OpenTelemetry. A coding agent can read a failing run, find the exception, and fix the code autonomously.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz3ewrpmwhbtgdg5n3w2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjz3ewrpmwhbtgdg5n3w2.png" alt="Nango observability dashboard showing detailed API integration logs" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://nango.dev/docs/updates/product#playground" rel="noopener noreferrer"&gt;Playground&lt;/a&gt;:&lt;/strong&gt; Trigger syncs and actions from the dashboard to validate end-to-end behavior before wiring them into your product.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://nango.dev/docs/updates/product#role-based-access-control-rbac" rel="noopener noreferrer"&gt;Role-based access control&lt;/a&gt;:&lt;/strong&gt; Control who on your team can edit, deploy, or manage integrations and connections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enterprise compliance and hosting:&lt;/strong&gt; &lt;a href="https://trust.nango.dev" rel="noopener noreferrer"&gt;SOC 2 Type II, GDPR, HIPAA&lt;/a&gt;. Enterprise self-hosting is available for teams that need full data isolation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Arcade
&lt;/h3&gt;

&lt;p&gt;Arcade is an MCP-native runtime for agent tool calling. It exposes a pre-built tool catalog, an SDK for custom MCP servers, and evaluation tools for testing agent behavior against scripted scenarios. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9xg19arcajickjutix33.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9xg19arcajickjutix33.png" alt="arcade-overview" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams building MCP-first agents focused on tool calling. Best suited if you don't need broader integration patterns like data syncs or webhooks, or AI coding agent support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MCP-native: every tool runs through the Model Context Protocol, which standardizes how agents discover and call tools.&lt;/li&gt;
&lt;li&gt;Automatic user permission checks before tool execution.&lt;/li&gt;
&lt;li&gt;SDK to build custom MCP servers that run on Arcade's runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arcade's SDK targets human developers who write and package custom MCP servers locally. There is no dedicated skill for Claude Code, Cursor, or similar agents. No integrated testing loop against a real connection, and no path for a coding agent to author and deploy a new tool end-to-end inside Arcade.&lt;/li&gt;
&lt;li&gt;Tool calls are the only pattern. No data syncs to feed agent context, no webhook processing, no unified API layer.&lt;/li&gt;
&lt;li&gt;First-party integrations are approximately 112 as of March 2026 (48 hand-built, 57 auto-generated, plus community contributions).&lt;/li&gt;
&lt;li&gt;No per-customer configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Composio
&lt;/h3&gt;

&lt;p&gt;Composio is a developer-facing tool library for AI agents. It ships managed auth and a large catalog of pre-built tools wrapped in frameworks like LangChain, CrewAI, Autogen, and the OpenAI Agents SDK.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcc8nypcv07n02pbel7o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcc8nypcv07n02pbel7o.png" alt="composio-overview" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that want an MCP server with a large pre-built catalog and managed auth. Best suited for internal productivity or personal automation agents rather than product teams needing custom tools or triggers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Catalog of 500+ apps accessible through one SDK.&lt;/li&gt;
&lt;li&gt;Managed authentication across supported APIs.&lt;/li&gt;
&lt;li&gt;Framework adapters for the most popular agent SDKs.&lt;/li&gt;
&lt;li&gt;SOC 2 and ISO certified.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No custom tools on the platform. You cannot deploy a tool you wrote yourself (or had a coding agent write) onto Composio's runtime. If a pre-built tool does not do what you need, you are blocked until Composio adds it.&lt;/li&gt;
&lt;li&gt;No custom triggers. Composio does not let you define webhook or schedule-based triggers for your integrations, so event-driven or scheduled work has to live elsewhere.&lt;/li&gt;
&lt;li&gt;There is no dedicated AI builder skill, no repo-level code-generation workflow, and no real API test loop to iterate on integration code.&lt;/li&gt;
&lt;li&gt;Tools are closed-source. You cannot inspect or modify the code of a pre-built tool.&lt;/li&gt;
&lt;li&gt;No data syncs to feed agent context, no webhook processing, no per-customer tool configuration.&lt;/li&gt;
&lt;li&gt;Observability is basic. You cannot add custom log messages, inspect full request and response details, or export traces via OpenTelemetry.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a deeper comparison, see our &lt;a href="https://www.nango.dev/blog/composio-alternatives" rel="noopener noreferrer"&gt;best Composio alternatives post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Nango&lt;/th&gt;
&lt;th&gt;Arcade&lt;/th&gt;
&lt;th&gt;Composio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AI coding agent skill (build-time)&lt;/td&gt;
&lt;td&gt;Yes, 18+ agents supported&lt;/td&gt;
&lt;td&gt;SDK only&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test against real API&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP server (runtime)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typed tool calls&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data syncs for agent context&lt;/td&gt;
&lt;td&gt;Yes (durable, incremental)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Webhook processing&lt;/td&gt;
&lt;td&gt;Yes (high-throughput)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-customer configuration&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Enterprise only&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;White-label auth UI&lt;/td&gt;
&lt;td&gt;Yes, drop-in&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open-source templates&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial (SDK)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosting&lt;/td&gt;
&lt;td&gt;Yes (Enterprise)&lt;/td&gt;
&lt;td&gt;VPC, on-prem&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary focus&lt;/td&gt;
&lt;td&gt;Full agentic platform (build + use)&lt;/td&gt;
&lt;td&gt;MCP runtime&lt;/td&gt;
&lt;td&gt;Tool library&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supported APIs&lt;/td&gt;
&lt;td&gt;700+&lt;/td&gt;
&lt;td&gt;~112 first-party&lt;/td&gt;
&lt;td&gt;500+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why AI coding agents change what "best" means
&lt;/h2&gt;

&lt;p&gt;The short answer is that "best" is no longer about who has the largest closed catalog. It is about the platform that lets your team ship integrations as fast as the coding agent can generate them, and exposes the result to AI agents reliably at runtime.&lt;/p&gt;

&lt;p&gt;Three loops compound here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Build loop:&lt;/strong&gt; An integration platform with good coding-agent skills, real-API testing, and secure, real-credential access lets an agent produce a working integration in under an hour. Without that loop, the agent hallucinates endpoints and ships non-working code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Run loop:&lt;/strong&gt; An agentic API integrations platform exposes every integration as a typed tool call or an MCP endpoint, with managed auth and observability, so the AI agent in your product can call it reliably in production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Maintain loop:&lt;/strong&gt; When an integration fails, the logs need to be accessible so that a coding agent, not just a human, can read the exception, trace the failing request, and ship a fix.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://nango.dev" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; is the only platform in this comparison that treats all three loops as first-class, and the only one where the same code an agent builds today runs unmodified in a hardened tenant-isolated runtime tomorrow.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What makes a platform "agentic"?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A platform is agentic when AI agents are first-class on both sides. Coding agents can build and deploy integrations with a real testing loop. Product-facing AI agents can call those integrations as tool calls, MCP endpoints, or triggers at runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is an agentic API integrations platform the same as a unified API?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. A unified API normalizes data from multiple providers into a single schema. It is built for backend engineers to query a fixed catalog. An agentic API integrations platform is built for AI agents on both sides: coding agents that produce integrations and product agents that consume them. Many agentic platforms can expose a unified API layer when needed, but that is one capability, not the whole category.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can AI coding agents like Claude Code or Cursor build integrations on these platforms?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Only where the platform ships a dedicated skill or harness. Nango's &lt;a href="https://nango.dev/docs/implementation-guides/platform/functions/leverage-ai-agents" rel="noopener noreferrer"&gt;AI builder skill&lt;/a&gt; works with 18+ coding agents and includes a test command that runs generated code against a real connection. Other platforms in this post provide SDKs but do not yet ship a production-grade coding-agent workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do AI agents need an MCP server?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not always. MCP is useful when the agent framework expects a standard protocol for discovering tools (for example, Claude Code or agents exposed through LangSmith). Many agent products also use REST APIs for integration, which is simpler and more deterministic. A good agentic platform supports both, so you pick per use case. See our note on &lt;a href="https://www.nango.dev/blog/build-reliable-tool-calls-for-ai-agents-integrating-with-external-apis#step-5-avoid-mcp-to-increase-control-and-reliability" rel="noopener noreferrer"&gt;avoiding MCP for production reliability&lt;/a&gt;, where custom tool calls are a better fit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does an agentic integration platform help with just-in-time integrations?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;Just-in-time integrations&lt;/a&gt; are generated on demand when a customer requests one in your product. The platform provides the sandbox where a coding agent writes the integration, the runtime that executes it with managed auth and tenant isolation, and the observability layer that lets agents read failures and fix themselves. Nango is the open-source factory for this pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use these platforms with LangChain, CrewAI, or the OpenAI Agents SDK?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. All three platforms in this post expose integrations via a combination of REST APIs, MCP servers, and native SDKs that work with LangChain, CrewAI, the OpenAI Agents SDK, the Vercel AI SDK, and the most popular agent frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The "best agentic API integrations platform" is a simple question with a layered answer: the platform needs to serve AI coding agents that build integrations and AI agents that use them, on a runtime that a team can trust in production.&lt;/p&gt;

&lt;p&gt;Nango is the only platform in this comparison that treats both sides as first-class. Coding agents build and maintain integrations through the AI builder skill, testing generated code against real APIs end to end. Product-facing AI agents consume those integrations through an MCP server, tool calls, webhooks, and data syncs. Integrations are code in your repo, running on a secure and scalable runtime, so your team stays in control of every layer while AI agents do most of the work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/just-in-time-integrations" rel="noopener noreferrer"&gt;The emergence of just-in-time integrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/using-ai-coding-agents-for-building-api-integrations" rel="noopener noreferrer"&gt;Using AI coding agents for building API integrations in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/best-ai-agent-integration-platforms" rel="noopener noreferrer"&gt;Best AI agent integration platforms to consider in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/best-ai-integration-platforms" rel="noopener noreferrer"&gt;Best AI integration platforms in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/best-practices-for-building-api-integrations-with-ai-agents" rel="noopener noreferrer"&gt;Best practices for building API integrations with AI agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/best-ai-agent-authentication" rel="noopener noreferrer"&gt;Best AI agent authentication platforms in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/why-ai-agents-meed-an-integrations-platform" rel="noopener noreferrer"&gt;Why AI agents need an integrations platform&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/how-is-nango-different-from-embedded-ipaas-or-unified-api" rel="noopener noreferrer"&gt;How is Nango different from embedded iPaaS or other unified APIs?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>agents</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Best Arcade.dev alternatives for AI agent integrations in 2026</title>
      <dc:creator>Sapnesh Naik</dc:creator>
      <pubDate>Tue, 21 Apr 2026 06:34:25 +0000</pubDate>
      <link>https://dev.to/nangohq/best-arcadedev-alternatives-for-ai-agent-integrations-in-2026-c1e</link>
      <guid>https://dev.to/nangohq/best-arcadedev-alternatives-for-ai-agent-integrations-in-2026-c1e</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Arcade.dev is an MCP runtime that executes authenticated tool calls for AI agents. It works well for MCP-first teams that need a hosted runtime and user-scoped auth. But production AI agents usually need more than tool calls: continuous data syncs for RAG, webhook ingestion, and deep observability across API integrations.&lt;/p&gt;

&lt;p&gt;If you are evaluating alternatives, pick the one that covers your full integration surface: not just the tool calls you need today, but the data syncs, webhooks, auth, and observability your agents will need once they ship to real customers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Top Arcade.dev alternatives for 2026:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nango:&lt;/strong&gt; Best for teams building production AI agent API integrations that need tool calls, data syncs, webhooks, and auth on a single code-first platform. Supports 700+ APIs with open-source tools and works with Claude Code, Cursor, and other AI coding agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composio:&lt;/strong&gt; An MCP-native alternative aimed mainly at internal and personal automation agents. Larger pre-built catalog than Arcade (500+ apps), but closed-source tools and no data syncs, webhooks, or per-customer configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pipedream Connect:&lt;/strong&gt; Fits teams that prefer a low-code, UI-based workflow builder with a large action library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merge Agent Handler:&lt;/strong&gt; Fits teams that want pre-built MCP tool-packs for common SaaS actions and don't need custom tool logic or data syncs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why teams look for Arcade.dev alternatives
&lt;/h2&gt;

&lt;p&gt;Arcade.dev positions itself as the MCP runtime that makes AI agents production-ready. It handles OAuth, runs tool calls, and supports server-level and tool-level authorization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmof8yo3das1eajabu46e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmof8yo3das1eajabu46e.png" alt="Arcade.dev platform overview" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That positioning works well for a specific profile: teams that are already committed to MCP, want a hosted runtime, and only need tool calls. But as teams move from prototyping to production API integrations, several limitations surface.&lt;/p&gt;

&lt;p&gt;Drawbacks of using Arcade for production AI agent integrations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tool calls only:&lt;/strong&gt; Arcade is a tool-calling runtime. It does not offer data syncs (for RAG pipelines), webhook ingestion, polling triggers, or unified APIs. If your AI product needs external data continuously kept up to date, or if it must react to events in Salesforce, HubSpot, or other systems, you need a separate platform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Narrow first-party catalog:&lt;/strong&gt; Arcade lists around 24 &lt;a href="https://docs.arcade.dev/home/auth-providers" rel="noopener noreferrer"&gt;first-party OAuth providers&lt;/a&gt;, which is materially smaller than other platforms in this comparison. Many APIs are only reachable through community MCP servers of varying quality and maintenance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx06cw172fsgz0zwu6xe1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx06cw172fsgz0zwu6xe1.png" alt="Arcade first-party OAuth provider list" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MCP-dependent architecture:&lt;/strong&gt; Every tool call flows through MCP. That is useful for prototyping, but &lt;a href="https://www.nango.dev/blog/build-reliable-tool-calls-for-ai-agents-integrating-with-external-apis#step-5-avoid-mcp-to-increase-control-and-reliability" rel="noopener noreferrer"&gt;generic MCP servers can reduce reliability&lt;/a&gt; in production: broad tool definitions inflate the LLM's context, and handing off multi-step logic to the agent increases hallucination risk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Limited observability:&lt;/strong&gt; Arcade provides basic logs of tool executions. Teams that need full request and response payload inspection, custom log messages inside a tool, or OpenTelemetry export find the logging surface narrow.&lt;br&gt;
&lt;strong&gt;For example:&lt;/strong&gt; During our testing, we ran a suggested &lt;code&gt;/reddit&lt;/code&gt; tool call inside Arcade's Playground. It failed with an &lt;code&gt;invalid Client ID&lt;/code&gt; error, but the failed execution never showed up in the Audit Logs page. Small gaps like this point to a platform that is still maturing in production, where several features are described as aspirational or in progress.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxt07k3sndx9qh540fgt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxt07k3sndx9qh540fgt.gif" alt="Arcade Playground failing a tool call with an invalid Client ID error" width="600" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7q6j78wwgjeg5bxalldo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7q6j78wwgjeg5bxalldo.png" alt="Arcade audit log missing the failed Playground execution" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No per-customer configuration:&lt;/strong&gt; Arcade tools are defined at the server level, not per tenant. There is no built-in support for tenant-specific custom field mappings, per-customer tool behavior, or custom auth validation. Every customer gets the same tool surface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These constraints are manageable for chat assistants and prototypes. They become real limits when AI agents are a core product feature that must run reliably across customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Arcade.dev alternatives
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Nango
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.nango.dev" rel="noopener noreferrer"&gt;Nango&lt;/a&gt; is an open-source integration platform for AI agents and SaaS products. It provides a unified interface for &lt;a href="https://www.nango.dev/blog/best-ai-agent-authentication" rel="noopener noreferrer"&gt;API auth&lt;/a&gt;, custom tool calls, data syncs, webhooks, and an &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/tool-calling/implement-mcp-server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;, all on a single platform.&lt;/p&gt;

&lt;p&gt;Nango supports &lt;a href="https://www.nango.dev/api-integrations" rel="noopener noreferrer"&gt;700+ APIs&lt;/a&gt; out of the box and is used by &lt;a href="https://www.nango.dev/customers" rel="noopener noreferrer"&gt;hundreds of fast-growing AI agent companies&lt;/a&gt; as core infrastructure for their API integrations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fux79eej6utc5brqczrzt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fux79eej6utc5brqczrzt.gif" alt="Nango pre-built integrations catalog" width="720" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams building production AI agent API integrations that need tool calls, data syncs for RAG, webhooks, and auth across a wide range of APIs on a single code-first platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Broad API coverage across 700+ APIs:&lt;/strong&gt; Pre-built auth for OAuth, API keys, JWT, basic auth, and the new &lt;a href="https://nango.dev/docs/updates/product#support-for-mcp-auth" rel="noopener noreferrer"&gt;MCP Auth&lt;/a&gt; standard. White-label by default, so end users authorize your app, not Nango. You can also contribute support for new APIs yourself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3bz8nm2ot4quprf7tp1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3bz8nm2ot4quprf7tp1.gif" alt="Nango white-label Connect UI for end-user authorization" width="600" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code-first with AI coding agent support:&lt;/strong&gt; Tool definitions are functions that live in your git repo and deploy through CI/CD. The &lt;a href="https://nango.dev/docs/implementation-guides/platform/functions/leverage-ai-agents" rel="noopener noreferrer"&gt;Nango AI Integration Builder&lt;/a&gt; works with Claude Code, Cursor, Codex, or any AI coding assistant, so you can generate and iterate on custom tools, syncs, and webhook handlers in minutes.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="c"&gt;# Install the Nango skills for your coding agent&lt;/span&gt;
  npx skills add NangoHQ/skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;  &lt;span class="c"&gt;&amp;lt;!-- Sample prompt --&amp;gt;&lt;/span&gt;

  Build a Nango sync that fetches events from the primary Google Calendar.

  Should run hourly, backfill on initial sync for the last 30 days and
  all future events. After the first run, only fetch future events
  incrementally.

  Return at least:
&lt;span class="p"&gt;  -&lt;/span&gt; Event title
&lt;span class="p"&gt;  -&lt;/span&gt; Start and end date
&lt;span class="p"&gt;  -&lt;/span&gt; Location
&lt;span class="p"&gt;  -&lt;/span&gt; RSVP status
&lt;span class="p"&gt;  -&lt;/span&gt; Attendees list (email, display name, response status)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fciasxlnsphj0z5cpvjzp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fciasxlnsphj0z5cpvjzp.gif" alt="Building a Nango sync with an AI coding agent" width="600" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open-source, customizable tools:&lt;/strong&gt; Nango's &lt;a href="https://github.com/NangoHQ/integration-templates" rel="noopener noreferrer"&gt;pre-built integration templates&lt;/a&gt; are open source. You can clone an existing tool, modify it for your use case with a coding agent, and deploy it to your account. This is the opposite of the closed tool model used by many MCP-first platforms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built-in MCP server:&lt;/strong&gt; Nango exposes your custom tool calls through an &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/tool-calling/implement-mcp-server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;. The flow is Agent to Nango MCP to your own custom tools. That keeps the agent's context focused on the specific tools you have built instead of flooding it with hundreds of generic ones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Beyond tool calls, on the same platform:&lt;/strong&gt; Native &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/syncs/implement-a-sync" rel="noopener noreferrer"&gt;resumable data syncs&lt;/a&gt; (for RAG), &lt;a href="https://nango.dev/docs/implementation-guides/use-cases/webhooks-from-external-apis" rel="noopener noreferrer"&gt;webhook processing&lt;/a&gt;, polling triggers, and per-customer configuration. A built-in &lt;a href="https://nango.dev/docs/updates/product#playground" rel="noopener noreferrer"&gt;Playground&lt;/a&gt; lets you test tool calls, syncs, and triggers interactively before wiring them into your agent, and &lt;a href="https://nango.dev/docs/updates/product#role-based-access-control-rbac" rel="noopener noreferrer"&gt;role-based access control (RBAC)&lt;/a&gt; scopes access across teammates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmoo96jidca9ccsxgwqin.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmoo96jidca9ccsxgwqin.gif" alt="Nango Playground for interactively testing tool calls, syncs, and triggers" width="560" height="320"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deep real-time observability:&lt;/strong&gt; Every operation generates &lt;a href="https://nango.dev/docs/guides/platform/observability" rel="noopener noreferrer"&gt;detailed logs&lt;/a&gt; with full API request and response details, error messages, and custom log messages. Everything exports via OpenTelemetry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjfsp2ggd5mt2xytu8cih.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjfsp2ggd5mt2xytu8cih.png" alt="Nango logs dashboard with full request and response details" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalable runtime with low overhead:&lt;/strong&gt; Nango adds less than 100ms overhead on tool calls, isolates each customer's executions with tenant-level fairness, and auto-scales under webhook bursts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enterprise-grade compliance:&lt;/strong&gt; &lt;a href="https://trust.nango.dev" rel="noopener noreferrer"&gt;SOC 2 Type II, GDPR, and HIPAA compliant&lt;/a&gt;. Enterprise self-hosting and VPC deployments available.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Composio
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Composio is an AI agent integration platform with a catalog of 500+ apps. It acts as an MCP gateway: every integration is automatically exposed through a standardized MCP interface, on top of managed OAuth and pre-built tool definitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fca43ntx3bfmw0uy4dzmo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fca43ntx3bfmw0uy4dzmo.png" alt="Composio MCP platform overview" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams building internal or personal automation agents that want an MCP-native alternative to Arcade with a larger pre-built catalog and managed auth, and that do not need data syncs, webhooks, or per-customer configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Larger catalog than Arcade:&lt;/strong&gt; Pre-built tool definitions across 500+ apps, covering Slack, GitHub, Notion, Gmail, Salesforce, and more.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MCP gateway:&lt;/strong&gt; Every integration is auto-exposed through MCP so you can expose tools to MCP-Compatible clients (like Claude Desktop, Cursor)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvxiozm9cw1um4ea0dt9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvxiozm9cw1um4ea0dt9.png" alt="Composio MCP gateway exposing tools to MCP-compatible clients" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Managed OAuth:&lt;/strong&gt; Handles token acquisition, refresh, and scope management out of the box.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Broad framework support:&lt;/strong&gt; Works with LangChain, CrewAI, OpenAI Agents SDK, and the Vercel AI SDK.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Closed-source tools:&lt;/strong&gt; You cannot inspect or modify the code of Composio's pre-built tools. If a tool does not match your requirements, you build a replacement from scratch outside the platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No data syncs or webhooks:&lt;/strong&gt; Composio focuses on tool calls. RAG pipelines that need continuously updated external data, or agents that react to real-time events, require a separate system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited per-customer configuration:&lt;/strong&gt; Every customer gets the same tool behavior. Tenant-specific field mappings, custom auth validation, or per-customer tool logic are not supported.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability constraints:&lt;/strong&gt; Basic execution logs. Custom log messages inside tool code and OpenTelemetry export are limited compared to code-first platforms.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feorjb0biozstrvqhcgqg.png" alt="Composio execution logs view" width="800" height="305"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Pipedream Connect
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pipedream Connect is the embedded version of Pipedream's serverless integration platform. It exposes MCP servers per app and gives agents access to a large library of pre-built actions across 2,800+ apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdbnqm2qldj8b3gsnqq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdbnqm2qldj8b3gsnqq6.png" alt="Pipedream Connect product overview" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that prefer a low-code workflow builder and need wide catalog coverage for internal-facing or lightly customized agent use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large action library:&lt;/strong&gt; 10,000+ pre-built actions across 2,800+ apps give agents a wide default surface area.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP server per app:&lt;/strong&gt; Dedicated MCP servers per supported app, so agents can discover and call tools through the protocol.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low-code workflow builder:&lt;/strong&gt; Useful for teams that want to assemble multi-step tool-call logic visually.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Acquired by Workday:&lt;/strong&gt; Pipedream was acquired by Workday (an Enterprise HR platform) in November 2025. You can read their announcement &lt;a href="https://pipedream.com/blog/pipedream-to-be-acquired-by-workday/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-standard action schemas:&lt;/strong&gt; Action inputs use Pipedream-specific types ("alert props," "dynamic props," "external props") that require a learning curve and limit compatibility with external tooling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex action configuration:&lt;/strong&gt; Most actions must be "configured" before they can run, often requiring 2-5 additional API requests. That adds latency and friction for background agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No data syncs:&lt;/strong&gt; Pipedream Connect does not offer scheduled or incremental data syncs, so RAG implementations need another platform for ongoing data ingestion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited white-label auth:&lt;/strong&gt; End users see Pipedream branding and consent to Pipedream during OAuth, which is a problem for enterprise-facing products.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Merge Agent Handler
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Merge Agent Handler is a separate product from Merge's traditional unified API. It lets teams create custom MCP servers with specific pre-built Merge integrations enabled, giving an AI agent a defined set of capabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9ohvgctjiddnhabz8iq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9ohvgctjiddnhabz8iq.png" alt="Merge Agent Handler MCP server configuration" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that only need pre-built MCP tool-packs for common SaaS actions (for example, fetch tickets from Linear, create an issue in GitHub) and do not need custom tool calls, data syncs, or custom object and field support for CRM and ERP integrations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pre-built tool-packs:&lt;/strong&gt; Bundle relevant integrations for a specific agent and restrict the available tools, for example a read-only tool-pack for ticketing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Playground:&lt;/strong&gt; A testing environment to validate MCP behavior before deploying.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public MCP import:&lt;/strong&gt; You can import any public MCP server and edit tool schemas to fit your agent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Narrow connector library:&lt;/strong&gt; Merge Agent Handler supports around 110 pre-built connectors. If the API you need is not covered, you fall back to public MCP servers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No custom tool calls:&lt;/strong&gt; You cannot build custom tool logic on the platform. Agents are constrained to the pre-built surface, which can force the LLM to chain multiple tool calls for a single business action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Custom fields support:&lt;/strong&gt; Pre-built tools do not handle custom fields or objects well, which is common in enterprise Salesforce or HubSpot deployments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No data syncs:&lt;/strong&gt; No support for continuous data syncs, so RAG pipelines need a second platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Auth gaps:&lt;/strong&gt; Some APIs, such as &lt;a href="https://developers.hubspot.com/docs/apps/developer-platform/build-apps/integrate-with-the-remote-hubspot-mcp-server#create-an-mcp-auth-app" rel="noopener noreferrer"&gt;HubSpot's remote MCP server&lt;/a&gt;, require MCP Auth. Merge Agent Handler currently supports standard (non-MCP) auth for most providers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison of Arcade.dev alternatives
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Nango&lt;/th&gt;
&lt;th&gt;Composio&lt;/th&gt;
&lt;th&gt;Pipedream Connect&lt;/th&gt;
&lt;th&gt;Merge Agent Handler&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary focus&lt;/td&gt;
&lt;td&gt;Agentic, code-first AI agent and product integrations&lt;/td&gt;
&lt;td&gt;MCP-first tool calling&lt;/td&gt;
&lt;td&gt;Low-code embedded workflows&lt;/td&gt;
&lt;td&gt;Pre-built MCP tool-packs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supported APIs&lt;/td&gt;
&lt;td&gt;700+&lt;/td&gt;
&lt;td&gt;500+&lt;/td&gt;
&lt;td&gt;2,800+&lt;/td&gt;
&lt;td&gt;~110&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool customization&lt;/td&gt;
&lt;td&gt;Full (code-first, open source)&lt;/td&gt;
&lt;td&gt;Limited (closed tools)&lt;/td&gt;
&lt;td&gt;Low-code workflows&lt;/td&gt;
&lt;td&gt;No custom tool code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI agent (LLM) tool calls&lt;/td&gt;
&lt;td&gt;Yes (custom, code-first)&lt;/td&gt;
&lt;td&gt;Yes (pre-built)&lt;/td&gt;
&lt;td&gt;Yes (pre-built actions)&lt;/td&gt;
&lt;td&gt;Yes (pre-built)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI coding agent support (Claude Code, Cursor)&lt;/td&gt;
&lt;td&gt;Yes (optimized tools and skills)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP server&lt;/td&gt;
&lt;td&gt;Yes (on your custom tools)&lt;/td&gt;
&lt;td&gt;Yes (auto on all tools)&lt;/td&gt;
&lt;td&gt;Yes (per app)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data syncs for RAG&lt;/td&gt;
&lt;td&gt;Yes (native, incremental)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Webhook processing&lt;/td&gt;
&lt;td&gt;Yes (high throughput)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Triggers only&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-customer configuration&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;td&gt;Deep (OpenTelemetry, custom logs)&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth model&lt;/td&gt;
&lt;td&gt;White-label (your brand)&lt;/td&gt;
&lt;td&gt;Managed&lt;/td&gt;
&lt;td&gt;Pipedream-branded&lt;/td&gt;
&lt;td&gt;Platform-managed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open source&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial (closed tools)&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosting&lt;/td&gt;
&lt;td&gt;Yes (Enterprise)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  How we evaluated these platforms
&lt;/h2&gt;

&lt;p&gt;We assessed each Arcade.dev alternative across five dimensions that matter for production AI agent integrations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Catalog breadth and extensibility:&lt;/strong&gt; How many APIs are supported out of the box? Can you add new APIs yourself without waiting on the vendor?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool customization:&lt;/strong&gt; Can you build and modify tool logic in code? Can AI coding agents (Claude Code, Cursor, Codex) help generate or refactor tools?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration patterns beyond tool calls:&lt;/strong&gt; Does the platform support data syncs for RAG, webhooks, polling triggers, and per-customer configuration?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability:&lt;/strong&gt; Are there full request and response logs, custom log messages inside tool code, and OpenTelemetry export?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment and auth model:&lt;/strong&gt; Is auth white-label and tenant-safe? Is self-hosting available for regulated workloads?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Which alternative should you choose?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;You are building production AI agent integrations with broad requirements:&lt;/strong&gt; Choose Nango. It is the only platform in this comparison that combines pre-built tool calls, data syncs, webhooks, and unified APIs on a single code-first platform, with 700+ APIs and AI coding agent support for building custom tools fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You want an MCP-native alternative to Arcade with a larger catalog:&lt;/strong&gt; Consider Nango or Composio. They both give you pre-built tools behind an MCP gateway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You prefer a low-code workflow builder with a large catalog:&lt;/strong&gt; Pipedream Connect fits, especially for internal-facing agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You only need standard, pre-built tool-packs:&lt;/strong&gt; Merge Agent Handler can work for ticketing, CRM reads, and other common SaaS actions. Confirm that your APIs are supported and that you do not need data syncs or deep customization.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is the best Arcade.dev alternative for production AI agents?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nango is a strong fit for teams building production AI agent API integrations. It supports 700+ APIs, code-first custom tool calls with AI coding agent support, data syncs for RAG, webhooks, and deep observability with OpenTelemetry. Unlike Arcade, it is not limited to tool calls and exposes an MCP server on top of your own custom tools instead of relying on public MCP servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Arcade.dev support data syncs or webhooks?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Arcade.dev is a tool-calling runtime. It does not provide scheduled or incremental data syncs, webhook ingestion, or polling triggers. If your AI agent needs continuously updated external data for a RAG pipeline, or must react to events in Salesforce or HubSpot, you need a separate platform. Nango supports all of these on a single platform alongside tool calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Arcade.dev open source?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arcade.dev's SDK and MCP server framework are open source, so you can build custom MCP servers and self-host. The platform itself (runtime, catalog, managed auth) is a hosted product. Nango, by contrast, is fully &lt;a href="https://github.com/NangoHQ/nango" rel="noopener noreferrer"&gt;open source on GitHub&lt;/a&gt;, and all of its pre-built integration templates are open and editable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use Arcade.dev alternatives with LangChain, CrewAI, or the OpenAI Agents SDK?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Nango, Composio, Pipedream Connect, and Merge Agent Handler all expose tools through standard interfaces (REST APIs and/or MCP servers) that work with any agent framework. Nango's MCP server and REST API integrate with LangChain, CrewAI, OpenAI Agents SDK, Vercel AI SDK, and Mastra. Composio is MCP-native and works with any MCP-compatible client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I build custom tools with Arcade.dev alternatives using AI coding agents?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No, not with Arcade itself. But Nango is designed for this: tool definitions are code, and the &lt;a href="https://nango.dev/docs/implementation-guides/platform/functions/leverage-ai-agents" rel="noopener noreferrer"&gt;Nango AI Integration Builder&lt;/a&gt; provides skills for Claude Code, Cursor, and other coding assistants to generate and refine tool calls, data syncs, and webhook handlers. Composio, Arcade, Pipedream Connect, and Merge Agent Handler do not ship dedicated AI coding agent integrations for building tools on their platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Arcade.dev is a focused MCP runtime that fits teams with strict MCP-first requirements and simple tool-calling workloads. Once AI agent integrations become a core product surface, the tool-calling-only scope, narrow first-party catalog, and basic observability start to matter.&lt;/p&gt;

&lt;p&gt;Nango covers the broadest set of production requirements on a single platform: 700+ APIs, custom tool calls, data syncs for RAG, webhooks, unified APIs, and deep observability, with AI coding agent support for building everything fast. Composio is a closer direct alternative to Arcade if your scope stays inside MCP tool calls. Pipedream Connect and Merge Agent Handler cover narrower low-code and pre-built use cases.&lt;/p&gt;

&lt;p&gt;Start with the hardest integration requirement in your product roadmap. The platform that handles it today will carry you further as your AI agents scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/build-reliable-tool-calls-for-ai-agents-integrating-with-external-apis" rel="noopener noreferrer"&gt;How to build reliable tool calls for AI agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/best-practices-for-building-api-integrations-with-ai-agents" rel="noopener noreferrer"&gt;Best practices for building API integrations with AI agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/best-ai-agent-integration-platforms" rel="noopener noreferrer"&gt;Best AI agent integration platforms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/best-ai-agent-authentication" rel="noopener noreferrer"&gt;Best AI agent authentication platforms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/composio-alternatives" rel="noopener noreferrer"&gt;Best Composio alternatives for AI agent integrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nango.dev/blog/pipedream-connect-alternatives" rel="noopener noreferrer"&gt;Best Pipedream Connect alternatives for AI integrations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>mcp</category>
      <category>api</category>
    </item>
  </channel>
</rss>
