title | sidebarTitle | icon |
---|---|---|
Node |
Node |
node |
The backend SDK lets you interact with the Nango API. It is available on NPM as @nangohq/node
.
Install it with your favorite package manager, e.g.:
npm i -S @nangohq/node
Instantiate the Nango
class:
import { Nango } from '@nangohq/node';
const nango = new Nango({ secretKey: '<SECRET-KEY>' });
Parameters
Get your secret key in the environment settings of the Nango UI. THis key should never be shared. <ResponseField name="host" type="string">
Omitting the host points to Nango Cloud. For local development, use `http://localhost:3003`. Use your instance URL if self-hosting.
</ResponseField>
</Expandable>
The Nango SDK is rate-limited to prevent abuse and ensure fair usage across all clients. The rate limit is enforced on a per-account basis, with a fixed window of time and a maximum number of requests allowed within that window.
If a client exceeds the rate limit, the API will respond with a 429 Too Many Requests
status code. In this case, the Retry-After
header is included, indicating the number of seconds the client should wait before making another request to avoid being rate-limited.
To handle rate limiting gracefully, clients should monitor for the 429 status code and honor the Retry-After
header value provided in the response.
// Example:
try {
const res = await nango.listIntegrations();
...
} catch(err) {
if (err.response.status === 429) {
const retryAfter = err.response.headers['retry-after'];
// wait and retry
...
}
...
}
Returns a list of integrations.
await nango.listIntegrations()
Example Response
```json { "configs": [ { "unique_key": "slack-nango-community", "provider": "slack" }, { "unique_key": "github-prod", "provider": "github" }, ] } ```Returns a specific integration.
await nango.getIntegration(<INTEGRATION-ID>);
Parameters
The integration ID.<ResponseField name="includeIntegrationCredentials" type="boolean">
Defaults to `false`.
</ResponseField>
Example Response
```json { "config": { "unique_key": "slack-nango-community", "provider": "slack", "syncs": [ { "name": "slack-messages", "created_at": "2023-10-16T08:45:26.241Z", "updated_at": "2023-10-16T08:45:26.241Z", "description": "Continuously fetch the latest Slack messages. Details: full refresh. Required scopes(s): channels:read, groups:read, mpim:read, im:read" } ], "actions": [ { "name": "github-list-repos-action", "created_at": "2023-10-17T17:28:03.839Z", "updated_at": "2023-10-17T17:28:03.839Z" } ] } } ```Create a new integration.
await nango.createIntegration(<PROVIDER-ID>, <INTEGRATION-ID>);
Parameters
The ID of the API provider in Nango (cf. [providers.yaml](https://nango.dev/providers.yaml) for a list of API provider IDs.)<ResponseField name="providerConfigKey" type="string" required>
The integration ID.
</ResponseField>
<ResponseField name="credentials" type="Record<string, string>">
The credentials to include depend on the specific integration that you want to create.
</ResponseField>
<ResponseField name="credentials" type="Record<string, string>">
<Expandable title="credentials" defaultOpen>
<ResponseField name="oauth_client_id" type="string">
The OAuth client ID.
</ResponseField>
<ResponseField name="oauth_client_secret" type="string">
The OAuth client secret.
</ResponseField>
<ResponseField name="oauth_scopes" type="string">
The list of OAuth scopes
</ResponseField>
</Expandable>
Example Response
```json { "config": { "unique_key": "slack-nango-community", "provider": "slack" } } ```Edits an integration (only for OAuth APIs).
await nango.updateIntegration(<PROVIDER-ID>, <INTEGRATION-ID>);
Parameters
The ID of the API provider in Nango (cf. [providers.yaml](https://nango.dev/providers.yaml) for a list of API provider IDs.)<ResponseField name="providerConfigKey" type="string" required>
The integration ID.
</ResponseField>
<ResponseField name="credentials" type="Record<string, string>">
The credentials to include depend on the specific integration that you want to create.
</ResponseField>
<ResponseField name="credentials" type="Record<string, string>">
<Expandable title="credentials" defaultOpen>
<ResponseField name="oauth_client_id" type="string">
The OAuth client ID.
</ResponseField>
<ResponseField name="oauth_client_secret" type="string">
The OAuth client secret.
</ResponseField>
<ResponseField name="oauth_scopes" type="string">
The list of OAuth scopes
</ResponseField>
</Expandable>
Example Response
```json { "config": { "unique_key": "slack-nango-community", "provider": "slack" } } ```Deletes a specific integration.
await nango.deleteIntegration(<INTEGRATION-ID>);
Parameters
The integration ID.Example Response
```json { "config": { "unique_key": "slack-nango-community", "provider": "slack" } } ```Returns a list of connections without credentials.
await nango.listConnections();
Parameters
Filter the list of connections based on this connection ID. If ommitted, returns all connections.Example Response
```json { "connections": [ { "id": 1, "connection_id": "test-1", "provider": "slack", "provider_config_key": "slack-nango-community", "created": "2023-06-03T14:53:22.051Z", "metadata": null }, { "id": 2, "connection_id": "test-2", "provider": "slack", "provider_config_key": "slack-nango-community", "created": "2023-06-03T15:00:14.945Z", "metadata": { "bot_id": "some-uuid" } } ] } ```Returns a specific connection with credentials.
await nango.getConnection();
If you do not want to deal with collecting & injecting credentials in requests for multiple authentication types, use the Proxy (step-by-step guide).
Every time you fetch the connection with this API endpoint, Nango will check if the access token has expired. If it has, it will refresh it.We recommend you always fetch the token just before you use it to make sure it is fresh!
Parameters
The integration ID.<ResponseField name="connectionId" type="string" required>
The connection ID.
</ResponseField>
<ResponseField name="forceRefresh" type="string">
Defaults to `false`. If `false`, the token will only be refreshed if it expires within 15 minutes. If `true`, a token refresh attempt will happen on each request. This is only useful for testing and should not be done at high traffic.
</ResponseField>
<ResponseField name="refreshToken" type="string">
Defaults to `false`. If `false`, the refresh token is not included in the response, otherwise it is. In production, it is not advised to return the refresh token, for security reasons, since only the access token is needed to sign requests.
</ResponseField>
Example Response
```json { "id": 18393, "created_at": "2023-03-08T09:43:03.725Z", "updated_at": "2023-03-08T09:43:03.725Z", "provider_config_key": "github", "connection_id": "1", "credentials": { "type": "OAUTH2", "access_token": "gho_tsXLG73f....", "refresh_token": "gho_fjofu84u9....", "expires_at": "2024-03-08T09:43:03.725Z", "raw": { // Raw token response from the OAuth provider: Contents vary! "access_token": "gho_tsXLG73f....", "refresh_token": "gho_fjofu84u9....", "token_type": "bearer", "scope": "public_repo,user" } }, "connection_config": { "subdomain": "myshop", "realmId": "XXXXX", "instance_id": "YYYYYYY" }, "account_id": 0, "metadata": { "myProperty": "yes", "filter": "closed=true" } } ```Returns a connection's metadata.
await nango.getMetadata('<INTEGRATION-ID>', 'CONNECTION-ID');
If you know the structure of the metadata, you can specify a type;
interface CustomMetadata {
anyKey: Record<string, string>;
}
const myTypedMetadata = await nango.getMetadata<CustomMetadata>('<INTEGRATION-ID>', '<CONNECTION-ID>');
Parameters
The integration ID of the connection.<ResponseField name="connectionId" type="string" required>
The connection ID.
</ResponseField>
Example Response
```json { "custom_key1": "custom_value1" } ```Set custom metadata for the connection (overrides existing metadata).
await nango.setMetadata('<INTEGRATION-ID>', 'CONNECTION-ID', { 'CUSTOM_KEY1': 'CUSTOM_VALUE1' });
Parameters
The integration ID of the connection.<ResponseField name="connectionId" type="string" required>
The connection ID.
</ResponseField>
<ResponseField name="metadata" type="Record<string, any>" required>
The custom metadata to store in the connection.
</ResponseField>
Response
Empty response.
Edit custom metadata for the connection. Only overrides specified properties, not the entire metadata.
await nango.updateMetadata('<INTEGRATION-ID>', 'CONNECTION-ID', { 'CUSTOM_KEY1': 'CUSTOM_VALUE1' });
Parameters
The integration ID of the connection.<ResponseField name="connectionId" type="string" required>
The connection ID.
</ResponseField>
<ResponseField name="metadata" type="Record<string, any>" required>
The custom metadata to store in the connection.
</ResponseField>
Response
Empty response.
Deletes a specific connection.
await nango.deleteConnection('<INTEGRATION-ID>', 'CONNECTION-ID');
Parameters
The integration ID of the connection.<ResponseField name="connectionId" type="string" required>
The connection ID.
</ResponseField>
Response
Empty response.
Return the configuration for all scripts
const scriptsConfig = await nango.getScriptsConfig();
Example Response
```json [ { "providerConfigKey": "demo-github-integration", "syncs": [ { "name": "github-issue-example", "type": "sync", "models": [ { "name": "GithubIssue", "fields": [ { "name": "id", "type": "integer" }, { "name": "owner", "type": "string" }, { "name": "repo", "type": "string" }, { "name": "issue_number", "type": "number" }, { "name": "title", "type": "string" }, { "name": "author", "type": "string" }, { "name": "author_id", "type": "string" }, { "name": "state", "type": "string" }, { "name": "date_created", "type": "date" }, { "name": "date_last_modified", "type": "date" }, { "name": "body", "type": "string" } ] } ], "sync_type": "FULL", "runs": "every half hour", "track_deletes": false, "auto_start": false, "last_deployed": "2024-02-28T20:16:38.052Z", "is_public": false, "pre_built": false, "version": "4", "attributes": {}, "input": {}, "returns": [ "GithubIssue" ], "description": "Fetches the Github issues from all a user's repositories.\nDetails: full sync, doesn't track deletes, metadata is not required.\n", "scopes": [ "public_repo" ], "endpoints": [ { "GET": "/github/issue-example" } ], "nango_yaml_version": "v2", "webhookSubscriptions": [] } ], "actions": [ { "name": "fetch-issues", "type": "action", "models": [ { "name": "GithubIssue", "fields": [ { "name": "id", "type": "integer" }, { "name": "owner", "type": "string" }, { "name": "repo", "type": "string" }, { "name": "issue_number", "type": "number" }, { "name": "title", "type": "string" }, { "name": "author", "type": "string" }, { "name": "author_id", "type": "string" }, { "name": "state", "type": "string" }, { "name": "date_created", "type": "date" }, { "name": "date_last_modified", "type": "date" }, { "name": "body", "type": "string" } ] } ], "runs": "", "is_public": false, "pre_built": false, "version": "4", "last_deployed": "2024-02-28T20:16:38.052Z", "attributes": {}, "returns": [ "GithubIssue" ], "description": "", "scopes": [], "input": {}, "endpoints": [ { "GET": "/github/issues" } ], "nango_yaml_version": "v2" } ], "postConnectionScripts": [], "provider": "github" } ] ```Returns the synced data.
import type { ModelName } from '<path-to-nango-integrations>/models'
const records = await nango.listRecords<ModelName>({
providerConfigKey: '<INTEGRATION-ID>',
connectionId: '<CONNECTION-ID>',
model: '<MODEL-NAME>'
});
Parameters
The integration ID. <ResponseField name="connectionId" type="string" required>
The connection ID.
</ResponseField>
<ResponseField name="model" type="string" required>
The name of the model of the data you want to retrieve.
</ResponseField>
<ResponseField name="cursor" type="string">
Each record from this endpoint comes with a synchronization cursor in `_nango_metadata.cursor`.
Save the last fetched record's cursor to track how far you've synced.
By providing the cursor to this method, you'll continue syncing from where you left off, receiving only post-cursor changes.
This same cursor is used to paginate through the results of this endpoint.
</ResponseField>
<ResponseField name="limit" type="number">
The maximum number of records to return. Defaults to 100.
</ResponseField>
<ResponseField name="filter" type="string">
Filter to only show results that have been added or updated or deleted.
Available options: added, updated, deleted
</ResponseField>
<ResponseField name="modifiedAfter" type="string">
Timestamp, e.g. 2023-05-31T11:46:13.390Z. If passed, only records modified after this timestamp are returned, otherwise all records are returned.
</ResponseField>
<ResponseField name="delta" type="string">
DEPRECATED (use modifiedAfter) Timestamp, e.g. 2023-05-31T11:46:13.390Z. If passed, only records modified after this timestamp are returned, otherwise all records are returned.
</ResponseField>
</Expandable>
Example Response
This endpoint returns a list of records, ordered by modification date ascending. If some records are updated while you paginate through this endpoint, you might see these records multiple times. ```json { records: [ { id: 123, ..., // Fields as specified in the model you queried _nango_metadata: { deleted_at: null, last_action: 'ADDED', first_seen_at: '2023-09-18T15:20:35.941305+00:00', last_modified_at: '2023-09-18T15:20:35.941305+00:00', cursor: 'MjAyNC0wMi0yNlQwMzowMDozOS42MjMzODgtMDU6MDB8fGVlMDYwM2E1LTEwNDktNDA4Zi05YTEwLTJjNzVmNDkwODNjYQ==' } }, ... ], next_cursor: "Y3JlYXRlZF9hdF4yMDIzLTExLTE3VDExOjQ3OjE0LjQ0NyswMjowMHxpZF4xYTE2MTYwMS0yMzk5LTQ4MzYtYWFiMi1mNjk1ZWI2YTZhYzI" } ```Triggers an additional, one-off execution of specified sync(s) for a given connection or all applicable connections if no connection is specified.
const records = await nango.triggerSync('<INTEGRATION-ID>', ['SYNC_NAME1', 'SYNC_NAME2'], '<CONNECTION_ID>');
Parameters
The integration ID. The name of the syncs to trigger. If the array is empty, all syncs are triggered. The connection ID. If omitted, the sync will trigger for all relevant connections.Response
Empty response.
Starts the schedule of specified sync(s) for a given connection or all applicable connections if no connection is specified.
await nango.startSync('<INTEGRATION-ID>', ['SYNC_NAME1', 'SYNC_NAME2'], '<CONNECTION_ID>')
Parameters
The integration ID. The name of the syncs that should be triggered. The connection ID. If ommitted, the sync will trigger for all relevant connections.Response
Empty response.
Pauses the schedule of specified sync(s) for a given connection or all applicable connections if no connection is specified.
await nango.startSync('<INTEGRATION-ID>', ['SYNC_NAME1', 'SYNC_NAME2'], '<CONNECTION_ID>')
Parameters
The integration ID. The name of the syncs that should be paused. The connection ID. If ommitted, the sync will pause for all relevant connections.Response
Empty response.
Get the status of specified sync(s) for a given connection or all applicable connections if no connection is specified.
await nango.syncStatus('<INTEGRATION-ID>', ['SYNC_NAME1', 'SYNC_NAME2'], '<CONNECTION_ID>')
Parameters
The integration ID. The name of the syncs you want to fetch a status for. Pass in "*" to return all syncs. The connection ID. If omitted, all connections will be surfaced.Response
```json { "syncs": [ { "id": "", "name": "", "status": "RUNNING", "type": "INCREMENTAL", "finishedAt": "", "nextScheduledSyncAt": "", "frequency": "", "latestResult": {} } ] } ```Override a sync's default frequency for a specific connection, or revert to the default frequency.
await nango.updateSyncConnectionFrequency('<INTEGRATION-ID>', 'SYNC_NAME', '<CONNECTION_ID>', '<FREQUENCY>')
Parameters
The integration ID. The name of the sync. The connection ID. The frequency you want to set (ex: 'every hour'). Set to `null` to revert to the default frequency.Response
```json { "frequency": "" } ```Retrieve the environment variables as added in the Nango dashboard.
await nango.getEnvironmentVariables();
Parameters
No parameters.
Response
```json [ { "name": "MY_SECRET_KEY", "value": "SK_373892NSHFNCOWFO..." } ] ```Triggers an action for a connection.
await nango.triggerAction('<INTEGRATION-ID>', '<CONNECTION_ID>', '<ACTION-NAME>', { 'custom_key1': 'custom_value1' });
Parameters
The integration ID. The connection ID. The name of the action to trigger. The necessary input for your action's `runAction` function.Response
```json { "your-properties": "The data returned by the action" } ```Triggers an action for a connection.
const res = await nango.get({
endpoint: '/endpoint',
providerConfigKey: '<INTEGRATION-ID>',
connectionId: '<CONNECTION-ID>',
baseUrlOverride: 'https://base-url.com'
});
Parameters
The endpoint of the request. The integration ID (for credential injection). The connection ID (for credential injection). The headers of the request. The query parameters of the request. The body of the request. The number of retries in case of failure (with exponential back-off). Optional, default 0. Array of additional status codes to retry a request in addition to the 5xx, 429, ECONNRESET, ETIMEDOUT, and ECONNABORTED The API base URL. Can be ommitted if the base URL is configured for this API in the [providers.yaml](https://nango.dev/providers.yaml). Override the decompress option when making requests. Optional, defaults to false The type of the response.Response
The response from the external API is passed back to you exactly as Nango gets it: - response code - response headers - response bodyTriggers an action for a connection.
const res = await nango.post({
endpoint: '/endpoint',
providerConfigKey: '<INTEGRATION-ID>',
connectionId: '<CONNECTION-ID>',
baseUrlOverride: 'https://base-url.com'
});
Parameters
The endpoint of the request. The integration ID (for credential injection). The connection ID (for credential injection). The headers of the request. The query parameters of the request. The body of the request. The number of retries in case of failure (with exponential back-off). Optional, default 0. Array of additional status codes to retry a request in addition to the 5xx, 429, ECONNRESET, ETIMEDOUT, and ECONNABORTED The API base URL. Can be ommitted if the base URL is configured for this API in the [providers.yaml](https://nango.dev/providers.yaml). Override the decompress option when making requests. Optional, defaults to false The type of the response.Response
The response from the external API is passed back to you exactly as Nango gets it: - response code - response headers - response bodyTriggers an action for a connection.
const res = await nango.put({
endpoint: '/endpoint',
providerConfigKey: '<INTEGRATION-ID>',
connectionId: '<CONNECTION-ID>',
baseUrlOverride: 'https://base-url.com'
});
Parameters
The endpoint of the request. The integration ID (for credential injection). The connection ID (for credential injection). The headers of the request. The query parameters of the request. The body of the request. The number of retries in case of failure (with exponential back-off). Optional, default 0. Array of additional status codes to retry a request in addition to the 5xx, 429, ECONNRESET, ETIMEDOUT, and ECONNABORTED The API base URL. Can be ommitted if the base URL is configured for this API in the [providers.yaml](https://nango.dev/providers.yaml). Override the decompress option when making requests. Optional, defaults to false The type of the response.Response
The response from the external API is passed back to you exactly as Nango gets it: - response code - response headers - response bodyTriggers an action for a connection.
const res = await nango.patch({
endpoint: '/endpoint',
providerConfigKey: '<INTEGRATION-ID>',
connectionId: '<CONNECTION-ID>',
baseUrlOverride: 'https://base-url.com'
});
Parameters
The endpoint of the request. The integration ID (for credential injection). The connection ID (for credential injection). The headers of the request. The query parameters of the request. The body of the request. The number of retries in case of failure (with exponential back-off). Optional, default 0. Array of additional status codes to retry a request in addition to the 5xx, 429, ECONNRESET, ETIMEDOUT, and ECONNABORTED The API base URL. Can be ommitted if the base URL is configured for this API in the [providers.yaml](https://nango.dev/providers.yaml). Override the decompress option when making requests. Optional, defaults to false The type of the response.Response
The response from the external API is passed back to you exactly as Nango gets it: - response code - response headers - response bodyTriggers an action for a connection.
const res = await nango.delete({
endpoint: '/endpoint',
providerConfigKey: '<INTEGRATION-ID>',
connectionId: '<CONNECTION-ID>',
baseUrlOverride: 'https://base-url.com'
});
Parameters
The endpoint of the request. The integration ID (for credential injection). The connection ID (for credential injection). The headers of the request. The query parameters of the request. The body of the request. The number of retries in case of failure (with exponential back-off). Optional, default 0. Array of additional status codes to retry a request in addition to the 5xx, 429, ECONNRESET, ETIMEDOUT, and ECONNABORTED The API base URL. Can be ommitted if the base URL is configured for this API in the [providers.yaml](https://nango.dev/providers.yaml). Override the decompress option when making requests. Optional, defaults to false The type of the response.Response
The response from the external API is passed back to you exactly as Nango gets it: - response code - response headers - response body