Skip to main content
Understanding these six concepts gives you a complete mental model of how Nango works. Each concept builds on the previous ones.
A provider is an external API that Nango supports — for example, GitHub, Slack, HubSpot, or Salesforce. Nango maintains configuration for each provider: the OAuth endpoints, credential format, base URL, and any quirks of that API.Nango supports 700+ providers out of the box. You never configure these low-level details yourself.How it relates to the rest: You pick a provider when you create an integration. The provider definition tells Nango how to handle auth and API requests for that service.
// List all available providers
const { providers } = await nango.listProviders({});
An integration is your configuration for connecting to a provider. It binds a provider (e.g. GitHub) to your Nango environment, including your OAuth credentials (client ID and secret), any custom scopes you need, and a unique identifier.You create integrations in the Nango dashboard or via the API. Each integration has a providerConfigKey — a unique ID you choose, like github or github-prod.How it relates to the rest: An integration is the template. Every connection is an instance of an integration — one per user.
// Retrieve an integration
const integration = await nango.getIntegration({ uniqueKey: 'github' });

// Create an integration programmatically
await nango.createIntegration({
  provider: 'github',
  unique_key: 'github',
  display_name: 'GitHub'
});
A connection represents a single user’s authorization to a single integration. When a user completes the auth flow, Nango creates a connection that stores their credentials (OAuth tokens, API keys, etc.) securely, handling token refresh automatically.Each connection is identified by:
  • providerConfigKey — the integration it belongs to (e.g. github)
  • connectionId — a string you choose to identify the user (e.g. user-123 or a UUID)
How it relates to the rest: Connections are what Auth creates. The Proxy and Functions both operate on behalf of a specific connection — you always pass providerConfigKey and connectionId together.
// Retrieve a connection and its credentials
const connection = await nango.getConnection('github', 'user-123');
console.log(connection.credentials);
// { type: 'OAUTH2', access_token: 'gho_...', expires_at: '...' }

// List all connections for an integration
const { connections } = await nango.listConnections({ integrationId: 'github' });
Auth is Nango’s managed authorization system. It embeds a white-label auth flow in your product and handles all credential management for you: OAuth 1.0 and 2.0 flows, API key collection, token refresh, credential storage, and multi-tenant connection management.Your frontend uses the @nangohq/frontend package to open the auth UI. Your backend never sees raw credentials unless you explicitly retrieve them.How it relates to the rest: Auth creates connections. Once a connection exists, you use the Proxy or Functions to act on it.
// Frontend: open Nango's managed Connect UI
import Nango from '@nangohq/frontend';

const nango = new Nango({ connectSessionToken: sessionToken });

nango.openConnectUI({
  onEvent: (event) => {
    if (event.type === 'close') {
      // Connection created — user is authorized
    }
  }
});
// Backend: create a session token before opening the UI
import { Nango } from '@nangohq/node';

const nango = new Nango({ secretKey: process.env.NANGO_SECRET_KEY });

const session = await nango.createConnectSession({
  end_user: { id: 'user-123', email: '[email protected]' },
  allowed_integrations: ['github']
});

// Pass session.data.token to your frontend
Nango supports OAuth 2.0, OAuth 1.0, API keys, Basic auth, JWT, and more. The auth method is determined by the provider — you don’t configure it manually.
The Proxy lets you make authenticated API requests on behalf of any connection without handling credentials directly. You send a request to Nango with an endpoint, providerConfigKey, and connectionId. Nango looks up the connection, injects the credentials, and forwards the request to the provider.The Proxy also handles:
  • Automatic token refresh before making the request
  • Configurable retries on failure
  • Rate limit handling
  • Request and response logging in the Nango dashboard
How it relates to the rest: The Proxy is the simplest way to use a connection after Auth creates it. For more complex patterns (polling, syncing, webhooks), use Functions.
import { Nango } from '@nangohq/node';

const nango = new Nango({ secretKey: process.env.NANGO_SECRET_KEY });

// GET request
const contacts = await nango.get({
  endpoint: '/v3/contacts',
  providerConfigKey: 'hubspot',
  connectionId: 'user-123'
});

// POST request with a body
const issue = await nango.post({
  endpoint: '/repos/my-org/my-repo/issues',
  providerConfigKey: 'github',
  connectionId: 'user-123',
  data: { title: 'Bug report', body: 'Something went wrong.' }
});

// With retries and custom headers
const response = await nango.get({
  endpoint: '/messages',
  providerConfigKey: 'gmail',
  connectionId: 'user-123',
  retries: 3,
  headers: { 'X-Custom-Header': 'value' }
});
Functions are TypeScript scripts you write (or generate with the AI builder) and deploy to Nango’s runtime. They run server-side on Nango’s infrastructure and have access to a nango object with built-in API access, storage, and observability.There are two types of functions:Syncs run on a schedule and continuously pull data from an external API into Nango’s cache. Your backend then reads this data via nango.listRecords(). Syncs handle incremental updates, pagination, and retries automatically.
// A sync that fetches GitHub issues on a schedule
export default async function run(nango: NangoSync) {
  const response = await nango.get({
    endpoint: '/repos/my-org/my-repo/issues',
    params: { state: 'open', per_page: '100' }
  });

  await nango.batchSave(response.data, 'GitHubIssue');
}
Actions run on demand, triggered by your backend. They execute a specific operation — creating a record, sending a message, looking up data — and return a result immediately.
// An action that creates a GitHub issue on demand
export default async function run(nango: NangoAction) {
  const { owner, repo, title, body } = nango.input;

  const response = await nango.post({
    endpoint: `/repos/${owner}/${repo}/issues`,
    data: { title, body }
  });

  return { id: response.data.id, url: response.data.html_url };
}
// Trigger the action from your backend
const result = await nango.triggerAction(
  'github',      // providerConfigKey
  'user-123',    // connectionId
  'create-issue',
  { owner: 'my-org', repo: 'my-repo', title: 'New issue', body: 'Details...' }
);
How it relates to the rest: Functions run on top of connections. They use the same providerConfigKey + connectionId pair to make authenticated requests, but they execute inside Nango’s runtime rather than your backend.
Use the AI builder to generate function code from a plain-English description of what you want to build.

How the concepts fit together

Here’s the typical flow for building an integration with Nango:
1

Choose a provider

Browse the 700+ supported APIs (Google, GitHub, Salesforce, Slack, and more) and pick the one you need.
2

Create an integration

Configure the integration in the Nango dashboard with your OAuth credentials and scopes.
3

Embed Auth in your product

Add Nango’s frontend SDK to open the managed auth UI when your users connect an account. Nango creates a connection for each user.
4

Build with the Proxy or Functions

Use the Proxy for direct API calls, or write Functions for syncing data, running scheduled tasks, or triggering actions.

Next steps

Quickstart

Make your first authenticated API call in under 5 minutes.

Auth guide

Embed managed auth for 700+ APIs in your product.

Proxy guide

Make authenticated API requests without handling credentials.

Functions guide

Write and deploy TypeScript integration functions.

Build docs developers (and LLMs) love