LoopFour

Connections API

Manage OAuth and API key connections for integrations

Connections API

Manage OAuth connections to external services. Connections are used by workflows to authenticate with integrated providers like Stripe, Salesforce, HubSpot, and more.

List Connections

Retrieve all connections for your company.

GET /api/v1/connections

Query Parameters

ParameterTypeDefaultDescription
providerstring-Filter by provider: stripe, salesforce, hubspot, etc.
statusstring-Filter: active, pending, error, expired, disconnected
limitnumber50Number of results (1-100)

Response

{
  "success": true,
  "data": [
    {
      "id": "conn_550e8400-e29b-41d4-a716-446655440000",
      "name": "Stripe Production",
      "provider": "stripe",
      "status": "active",
      "externalAccountId": "acct_xxx",
      "lastSyncedAt": "2024-01-15T10:30:00.000Z",
      "createdAt": "2024-01-01T10:00:00.000Z",
      "updatedAt": "2024-01-15T10:30:00.000Z"
    },
    {
      "id": "conn_660e8400-e29b-41d4-a716-446655440001",
      "name": "HubSpot CRM",
      "provider": "hubspot",
      "status": "active",
      "externalAccountId": "123456",
      "lastSyncedAt": "2024-01-15T09:00:00.000Z",
      "createdAt": "2024-01-05T10:00:00.000Z",
      "updatedAt": "2024-01-15T09:00:00.000Z"
    }
  ],
  "meta": {
    "hasMore": false
  }
}

Example

curl -X GET "http://localhost:3000/api/v1/connections?provider=stripe" \
  -H "x-api-key: YOUR_API_KEY"

Get Auth URL

Generate an OAuth authorization URL for a provider. This creates a pending connection and returns the URL to redirect the user to.

GET /api/v1/connections/:provider/auth-url

Path Parameters

ParameterTypeDescription
providerstringProvider name: stripe, salesforce, hubspot, quickbooks, pandadoc, netsuite, slack, gmail

Query Parameters

ParameterTypeRequiredDescription
redirectUrlstringNoURL to redirect after OAuth completion
connectionNamestringNoCustom name for the connection

Response

{
  "success": true,
  "data": {
    "connectionId": "conn_550e8400-e29b-41d4-a716-446655440000",
    "provider": "stripe",
    "authUrl": "https://connect.stripe.com/oauth/authorize?client_id=xxx&redirect_uri=xxx&state=xxx",
    "isNew": true,
    "message": "Redirect user to authUrl to complete OAuth authorization"
  }
}

Example

curl -X GET "http://localhost:3000/api/v1/connections/stripe/auth-url?redirectUrl=https://app.example.com/settings/connections" \
  -H "x-api-key: YOUR_API_KEY"

Re-authorization

If a connection already exists but is in error or disconnected status, calling this endpoint will return a new auth URL for re-authorization:

{
  "success": true,
  "data": {
    "connectionId": "conn_existing",
    "provider": "stripe",
    "authUrl": "https://connect.stripe.com/oauth/authorize?...",
    "isNew": false,
    "message": "Redirect user to authUrl to complete OAuth authorization"
  }
}

Error Response (Active Connection Exists)

{
  "success": false,
  "error": {
    "code": "BAD_REQUEST",
    "message": "Active connection already exists for stripe. Disconnect first to re-authorize."
  }
}

OAuth Callback

Handle the OAuth callback from the provider. This endpoint is called by Nango after the user completes authorization.

GET /api/v1/connections/:provider/callback

This endpoint does not require authentication as it handles redirects from the OAuth provider.

Query Parameters

ParameterTypeDescription
connectionIdstringThe connection ID from the auth flow
successstring"true" or "false"
errorstringError message if authorization failed
redirectUrlstringURL to redirect the user to

Successful Authorization

If redirectUrl is provided, redirects to:

https://app.example.com/settings/connections?success=true&connectionId=xxx&provider=stripe

Otherwise returns:

{
  "success": true,
  "data": {
    "connectionId": "conn_xxx",
    "provider": "stripe",
    "status": "active",
    "message": "OAuth authorization completed successfully"
  }
}

Failed Authorization

If redirectUrl is provided, redirects to:

https://app.example.com/settings/connections?error=access_denied&connectionId=xxx

Create Connection

Initiate a new connection (starts OAuth flow).

POST /api/v1/connections

Request Body

FieldTypeRequiredDescription
namestringYesDisplay name for the connection
providerstringYesProvider name
metadataobjectNoAdditional metadata

Example Request

{
  "name": "Production Stripe",
  "provider": "stripe",
  "metadata": {
    "environment": "production"
  }
}

Response (201 Created)

{
  "success": true,
  "data": {
    "id": "conn_550e8400-e29b-41d4-a716-446655440000",
    "name": "Production Stripe",
    "provider": "stripe",
    "status": "pending",
    "oauthUrl": "https://api.nango.dev/oauth/connect/stripe?connection_id=xxx&public_key=xxx",
    "message": "Redirect user to oauthUrl to complete connection"
  }
}

Get Connection

Retrieve details of a specific connection.

GET /api/v1/connections/:id

Response

{
  "success": true,
  "data": {
    "id": "conn_550e8400-e29b-41d4-a716-446655440000",
    "name": "Stripe Production",
    "provider": "stripe",
    "status": "active",
    "externalAccountId": "acct_xxx",
    "lastSyncedAt": "2024-01-15T10:30:00.000Z",
    "metadata": {
      "environment": "production"
    },
    "createdAt": "2024-01-01T10:00:00.000Z",
    "updatedAt": "2024-01-15T10:30:00.000Z"
  }
}

Delete Connection

Revoke and delete a connection. This also removes the connection from Nango.

DELETE /api/v1/connections/:id

Response

{
  "success": true,
  "data": {
    "deleted": true
  }
}

Deleting a connection will cause workflows using this connection to fail. Make sure to update or pause affected workflows first.

Refresh Connection

Manually refresh connection credentials. Useful when credentials are about to expire.

POST /api/v1/connections/:id/refresh

Response

{
  "success": true,
  "data": {
    "id": "conn_550e8400-e29b-41d4-a716-446655440000",
    "lastSyncedAt": "2024-01-15T10:35:00.000Z",
    "message": "Connection refresh completed"
  }
}

Error Response (Refresh Failed)

If the refresh fails, the connection status is updated to error:

{
  "success": false,
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "Failed to refresh credentials: Token expired"
  }
}

Verify Connection

Test connection health by verifying credentials with the provider.

POST /api/v1/connections/:id/verify

Response (Healthy Connection)

{
  "success": true,
  "data": {
    "healthy": true,
    "connectionId": "conn_550e8400-e29b-41d4-a716-446655440000",
    "provider": "stripe",
    "status": "active",
    "externalAccountId": "acct_xxx",
    "error": null,
    "checkedAt": "2024-01-15T10:35:00.000Z"
  }
}

Response (Unhealthy Connection)

{
  "success": true,
  "data": {
    "healthy": false,
    "connectionId": "conn_550e8400-e29b-41d4-a716-446655440000",
    "provider": "stripe",
    "status": "error",
    "externalAccountId": null,
    "error": "Invalid API key provided",
    "checkedAt": "2024-01-15T10:35:00.000Z"
  }
}

Response (Not Yet Authorized)

{
  "success": true,
  "data": {
    "healthy": false,
    "connectionId": "conn_550e8400-e29b-41d4-a716-446655440000",
    "provider": "stripe",
    "status": "pending",
    "error": "Connection not yet authorized - complete OAuth flow first",
    "checkedAt": "2024-01-15T10:35:00.000Z"
  }
}

Connection Statuses

StatusDescription
pendingOAuth flow started but not completed
activeConnection is working properly
errorConnection has an issue (check errorMessage)
expiredOAuth token has expired, needs re-authorization
disconnectedUser revoked access or connection was disconnected

Supported Providers

ProviderOAuthDescription
stripeYesPayment processing
salesforceYesCRM
hubspotYesMarketing/CRM
quickbooksYesAccounting
pandadocYesDocument signing
netsuiteYesERP
slackYesMessaging
gmailYesEmail (Google)

OAuth Flow

The typical OAuth flow for connecting a provider:

1. Your app calls GET /api/v1/connections/:provider/auth-url
2. API returns authUrl and connectionId
3. Your app redirects user to authUrl
4. User authorizes in provider's UI
5. Provider redirects to Nango callback
6. Nango redirects to /api/v1/connections/:provider/callback
7. API updates connection status to 'active'
8. User is redirected to your redirectUrl

Example Flow (JavaScript)

// Step 1: Get auth URL
const authResponse = await fetch(
  `http://localhost:3000/api/v1/connections/stripe/auth-url?redirectUrl=${encodeURIComponent('https://app.example.com/settings')}`,
  { headers: { 'x-api-key': API_KEY } }
);
const { data } = await authResponse.json();
 
// Step 2: Redirect user to OAuth
window.location.href = data.authUrl;
 
// Step 3: Handle callback (on your redirect page)
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('success') === 'true') {
  const connectionId = urlParams.get('connectionId');
  console.log('Connection created:', connectionId);
} else {
  const error = urlParams.get('error');
  console.error('OAuth failed:', error);
}

Error Responses

Connection Not Found (404)

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Connection not found"
  }
}

Active Connection Exists (400)

{
  "success": false,
  "error": {
    "code": "BAD_REQUEST",
    "message": "Active connection already exists for stripe. Disconnect first to re-authorize."
  }
}