Step 1: Setup the Nango CLI & nango-integrations folder
Install the Nango CLI globally:nango-integrations
. You can place this folder anywhere in your file tree, but we recommend you place it at the root level of your project.
In the folder where you want your integrations folder (e.g. root of your project), run:
Understanding the Our CLI helps you manage this directory, create scaffolds, validates the configuration, etc.
nango-integrations
folderSyncs & actions have two parts:- A global config file called
nango.yaml
with sync/action names, frequency, models, etc. - A small typescript file per sync/action, which defines the logic.
nango-integrations
in your own code repository.nango-integrations structure
.env
file in ./nango-integrations
):
prod
and dev
secret keys from the Project Settings tab (toggle between the prod
and dev
environment in the left nav bar).
Step 2: Create a sync or action
Configure your sync/action in nango.yaml
Open the nango.yaml
file inside the nango-integrations
folder and inspect its field:
nango.yaml
Possible model types include
string
, boolean
, number
, date
, null
as well as arrays & nested objects. Union types can be used with |
.
Model names must be singular as they are a single entity.A more complex example:nango.yaml
to provide type safety when:
- you write sync/action scripts
- sync/action scripts run
- you fetch the synced data for syncs, or pass in parameters and get back a response for actions
- A sync can return multiple data models: e.g.
AsanaTasks
andAsanaComments
- Multiple syncs can return the same data model: e.g. Asana and Linear can both return a
Task
Write your sync
Modify the configuration ofnango.yaml
as you need and run (in ./nango-integrations
):
[sync-name].ts
) which contains the following template (for the Asana example above):
asana-tasks.ts
- incrementally fetch data from external APIs (with HTTP requests)
- transform the external data into the models that you defined in
nango.yaml
Your sync scripts are deployed to Nango and automatically run on a schedule. Nango offers you multiple environments (dev & prod) to test & deploy your syncs.Because your scripts run in Nango’s cloud, you cannot import additional modules (external or relative) in the sync scripts at the moment (we plan to resolve this limitation in the near future).
./nango-integrations
:
nango-integrations
folder for changes and compiles the sync scripts & data models as needed. If there are any compilation errors (e.g. due to type issues), you can see them in the terminal where nango dev
runs.
Fill in the fetchData
method with your integration code (in the example here, we fetch tasks from Asana):
asana-taks.ts
await nango.batchSave(data, 'ModelName');
. You can split the data into as many batches as needed.
To make API requests, use the proxy exposed by the
nango
object (Proxy guide).nango.get({})
nango.post({})
- etc
providerConfigKey
and connectionId
fields in the call to the Proxy. They are automatically injected.The 1st run of the sync is called “initial”, meaning it fetches all the historical data (unless you have defined a backfill limit in the sync script). On the 1st run,
nango.lastSyncDate
will be null
.Subsequent runs are called “incremental”. They should only fetch the created & updated data. It’s up to you to use the nango.lastSyncDate
value to fetch the incremental changes.Use
await nango.log()
to log data from within integration scripts.Write your action
Modify the configuration ofnango.yaml
as you need and run (in ./nango-integrations
):
[action-name].ts
) which contains the following template (for the Slack example above):
slack-alert.ts
Your action scripts are deployed to Nango and automatically run on a schedule. Nango offers you multiple environments (dev & prod) to test & deploy your actions.Because your scripts run in Nango’s cloud, you cannot import additional modules (external or relative) in the action scripts at the moment (we plan to resolve this limitation in the near future).
./nango-integrations
:
nango-integrations
folder for changes and compiles the action scripts & data models as needed. If there are any compilation errors (e.g. due to type issues), you can see them in the terminal where nango dev
runs.
Fill in the runAction
method with your integration code:
slack-alert.ts
runAction
function.
To make API requests, use the proxy exposed by the
nango
object (Proxy guide).nango.get({})
nango.post({})
- etc
providerConfigKey
and connectionId
fields in the call to the Proxy. They are automatically injected (as well as credentials).Use
await nango.log()
to log data from within integration scripts.Dry run your sync/action
Before you deploy your sync to your cloud account, you can test it locally to make sure it works as expected. You will probably use this a lot whilst developing your sync. Use thedryrun
function of the CLI:
By default, the connection ID is fetched from your
Dev
environment. You can fetch connections from your Prod
environment with the -e prod
flag.To test incremental sync runs, add the -l
flag (which will populate the nango.lastSyncDate
value in your script):Step 3: Deploy a sync/action
1. Deploy to theDev
environment
When your sync script is ready, you can deploy it to your Dev
environment in Nango:
When you deploy your sync, Nango automatically adds it to all the existing connections of the integration, and starts syncing their data.It will also add the sync to any new connection that is created (OAuth flow completes) for the integration.You can see all syncs (and their status) for a connection in the dashboard:

Prod
environment
Once you are ready to deploy to production, run:
Advanced Configuration
Handling API rate-limits
Nango has currently two approaches to handle rate limits, a generic/naive one and an API-specific one. The generic & naive approach is based on retries & exponential-backoff. When you make network requests with the proxy in a sync with a high number of retries, exponential back-off will increase the delay between retries, augmenting the chances to go back under the rate-limit. But this “blind” approach is inefficient both in terms of optimising the time between requests and avoiding complex rate-limits. The API-specific approach is based on reading the rate-limit headers returned by the external APIs. Nango observes these headers and pauses the sync job until the rate-limit is passed. This approach has the benefit of being more efficient both for minimizing sync durations and avoid failures due to rate-limiting. This second approach requires to edit Nango’s providers.yaml file to indicate the rate-limit header name for a specific API (in theretry
entry, under at
or after
fields):
Github example:
Handling record deletion
In Nango, syncs can detect record deletions. These deleted records are not removed, but are flagged as “soft deleted” using metadata. This ensures that you can still view the records in Nango, but recognize them as deleted entities. Each record has a_nango_metadata
field that carries metadata, including deletion information:
batchDelete
method in your script to flag records as deleted:
users
) need to provide just the unique id
field.
Full refresh syncs
For syncs that operate in full refresh mode, add the track_deletes: true
field to your nango.yaml
configuration for the particular sync. This ensures that when a record previously returned by the sync script isn’t returned in the latest run, Nango will flag it as deleted.