• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
nbbaier

nbbaier

pipedream-connect

Remix of valdottown/pipedream-connect
Public
Like
pipedream-connect
Home
Code
11
backend
4
frontend
2
sdk
1
.gitignore
.vtignore
AGENTS.md
MIGRATE.md
MIGRATION_PLAN.md
README.md
biome.json
deno.json
Branches
1
Pull requests
Remixes
History
Environment variables
4
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
MIGRATE.md
Code
/
MIGRATE.md
Search
10/6/2025
Viewing readonly version of main branch: v51
View latest version
MIGRATE.md

Migrating from v1.x

This guide will help you migrate your existing Pipedream SDK v1.x integration to the latest version.

Table of contents

  • Migrating from v1.x
    • Table of contents
    • Deprecation
    • Breaking changes
    • Client initialization
      • Server-side
        • v1.x (old)
        • v2.x (new)
      • Browser-side
        • v1.x (old)
        • v2.x (new)
      • Environment variables
    • Method migration
      • Method and parameter naming
      • Migration examples
        • Running actions
          • v1.x (old)
          • v2.x (new)
        • Deploying triggers
          • v1.x (old)
          • v2.x (new)
        • Managing accounts
          • v1.x (old)
          • v2.x (new)
        • Creating connect tokens
          • v1.x (old)
          • v2.x (new)
        • Validating connect tokens
          • v1.x (old)
          • v2.x (new)
        • Configuring component props
          • v1.x (old)
          • v2.x (new)
        • Deleting accounts
          • v1.x (old)
          • v2.x (new)
        • Getting project info
          • v1.x (old)
          • v2.x (new)
        • Making proxy requests
          • v1.x (old)
          • v2.x (new)
        • Invoking workflows
          • v1.x (old)
          • v2.x (new)
    • Namespace mapping
    • New features in v2.x
      • Full TypeScript support
      • Pagination support
      • Enhanced error handling
      • Request options
      • Abort signals
      • Raw response access
    • Browser/Server Environment Separation
      • Package.json Export Structure
      • Import Recommendations
    • Additional namespaces
    • Partial migration
    • Important removed functionality
    • Migration checklist

Deprecation

The v1.x version of the Pipedream SDK is now deprecated. This means that no changes will be made to this version unless there are critical security issues. We recommend that you migrate to the latest version of the SDK to take advantage of new features, improvements, and bug fixes if possible.

Breaking changes

The new SDK version introduces several breaking changes that you need to be aware of when migrating from v1.x. Below is a summary of the most significant changes:

  • Namespaced Methods: Methods are now namespaced by the resource they act upon. For example, instead of using client.runAction(), you now use client.actions.run().
  • Automatic Snake Case Conversion: While the TypeScript interfaces use camelCase for better developer experience, the SDK automatically converts these to snake_case when making API calls to align with our OpenAPI spec.
  • Client Initialization: The createBackendClient() and createFrontendClient() methods have been replaced with a new PipedreamClient class. Note: The v1.x BrowserClient class has been replaced with PipedreamClient in the browser context.
  • TypeScript Types: All TypeScript types are now exported for better type safety.
  • Authentication Changes: The rawAccessToken() method is now available as a rawAccessToken getter property on the server-side SDK.
  • Environment Variables: The SDK now supports automatic configuration via environment variables (see below).

Client initialization

Server-side

For server-side applications, we recommend using the PipedreamClient wrapper class, which simplifies OAuth token management.

v1.x (old)

import { createBackendClient } from "@pipedream/sdk"; const client = createBackendClient({ credentials: { clientId: "your-client-id", clientSecret: "your-client-secret", }, projectId: "your-project-id", environment: "development", // or 'production' });

v2.x (new)

import { PipedreamClient } from "@pipedream/sdk"; const client = new PipedreamClient({ clientId: "your-client-id", clientSecret: "your-client-secret", projectId: "your-project-id", projectEnvironment: "development", // or 'production' });

Browser-side

For browser-side applications, you should use the PipedreamClient class and authenticate using a connect_token obtained from your backend.

v1.x (old)

import { createFrontendClient } from "@pipedream/sdk"; const frontendClient = createFrontendClient({ environment: "development", credentials: { token: "connect-token-from-backend", }, });

v2.x (new)

The v2.x SDK provides two options for browser-side usage:

Option 1: Using PipedreamClient with token callback (for dynamic token management)

import { PipedreamClient } from "@pipedream/sdk"; const tokenCallback = async ({ externalUserId }) => { // Call your backend to get a connect token const response = await fetch("/api/pipedream/token", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ externalUserId }), }); return response.json(); }; const clientWithToken = new PipedreamClient({ tokenCallback, projectId: "your-project-id", projectEnvironment: "development", // or 'production' });

Option 2: Using createFrontendClient with connect token (for simple token-based auth)

// Explicit browser import (recommended for browser apps) import { createFrontendClient, type PipedreamClient, } from "@pipedream/sdk/browser"; // Or automatic browser resolution import { createFrontendClient, type PipedreamClient } from "@pipedream/sdk"; // `tokenCallback` is also supported here const client: PipedreamClient = createFrontendClient({ token: "connect-token", externalUserId: "user-123", }); // Connect an account using Pipedream Connect client.connectAccount({ app: "github", onSuccess: (result) => { console.log("Account connected:", result.id); }, onError: (error) => { console.error("Connection failed:", error); }, }); // Get user's accounts const accounts = await client.getAccounts();

Environment variables

The v2.x SDK supports automatic configuration via environment variables:

// These environment variables are automatically used if set: // PIPEDREAM_CLIENT_ID // PIPEDREAM_CLIENT_SECRET // PIPEDREAM_PROJECT_ID // PIPEDREAM_PROJECT_ENVIRONMENT (defaults to 'production') // You can initialize the client with minimal configuration const client = new PipedreamClient({ projectId: "your-project-id", // Can also come from PIPEDREAM_PROJECT_ID }); // If environment variables are set, you can even do: const client = new PipedreamClient(); // This will use PIPEDREAM_CLIENT_ID, PIPEDREAM_CLIENT_SECRET, and PIPEDREAM_PROJECT_ID

Method migration

Method and parameter naming

In v2.x, all methods are namespaced. While you write TypeScript code using camelCase (e.g., externalUserId), the SDK automatically converts these to snake_case (e.g., external_user_id) when making API calls. For example, client.runAction({ externalUserId: '...' }) becomes client.actions.run({ externalUserId: '...' }) in your code, but the SDK sends external_user_id to the API. This automatic conversion aligns with the OpenAPI spec, but does not apply to the following arguments:

  1. Client constructor parameters like clientId, clientSecret, projectId, projectEnvironment, and workflowDomain.
  2. The props listed under configuredProps (the naming follows whatever the corresponding component defines).
  3. Request options like timeoutInSeconds, maxRetries, and headers (these remain in camelCase as they are not part of the API request body).

Migration examples

Running actions

v1.x (old)
const result = await client.runAction({ externalUserId: "jverce", actionId: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, });
v2.x (new)
const result = await client.actions.run({ externalUserId: "jverce", id: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, });

Deploying triggers

v1.x (old)
const trigger = await client.deployTrigger({ externalUserId: "jverce", triggerId: "gitlab-new-issue", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD", }, projectId: 45672541, }, webhookUrl: "https://events.example.com/gitlab-new-issue", });
v2.x (new)
const trigger = await client.triggers.deploy({ externalUserId: "jverce", id: "gitlab-new-issue", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD", }, projectId: 45672541, }, webhookUrl: "https://events.example.com/gitlab-new-issue", });

Managing accounts

v1.x (old)
// List accounts const accounts = await client.getAccounts({ external_user_id: "jverce", include_credentials: true, }); // Get specific account const account = await client.getAccountById("apn_kVh9AoD", { include_credentials: true, });
v2.x (new)
// List accounts const accounts = await client.accounts.list({ externalUserId: "jverce", includeCredentials: true, }); // Get specific account const account = await client.accounts.retrieve("apn_kVh9AoD", { includeCredentials: true, });

Creating connect tokens

v1.x (old)
const token = await client.createConnectToken({ external_user_id: "jverce", });
v2.x (new)
const token = await client.tokens.create({ externalUserId: "jverce", });

Validating connect tokens

v1.x (old)
// validateConnectToken was available in v1.x const isValid = await client.validateConnectToken({ token: "connect-token-to-validate", });
v2.x (new)
const validation = await client.tokens.validate({ token: "connect-token-to-validate", });

Configuring component props

v1.x (old)
const response = await client.configureComponent({ externalUserId: "jverce", componentId: "gitlab-new-issue", propName: "projectId", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, }, });
v2.x (new)
const response = await client.components.configureProp({ externalUserId: "jverce", id: "gitlab-new-issue", propName: "projectId", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, }, });

Deleting accounts

v1.x (old)
// Delete specific account await client.deleteAccount("account-id"); // Delete all accounts for an app await client.deleteAccountsByApp("app-id"); // Delete external user await client.deleteExternalUser("jverce");
v2.x (new)
// Delete specific account await client.accounts.delete("account-id"); // Delete all accounts for an app - functionality removed // Consider using accounts.list() and deleting individually // Delete external user - use users namespace await client.users.delete({ externalUserId: "jverce", });

Getting project info

v1.x (old)
const projectInfo = await client.getProjectInfo(); console.log(projectInfo.apps);
v2.x (new)
const project = await client.projects.retrieve(); console.log(project);

Making proxy requests

v1.x (old)
// v1.x uses a single method with two parameters const response = await client.makeProxyRequest( { searchParams: { external_user_id: "jverce", account_id: "apn_kVh9AoD", }, }, { url: "https://api.example.com/data", options: { method: "GET", headers: { Accept: "application/json", }, }, } ); // POST request with body const postResponse = await client.makeProxyRequest( { searchParams: { external_user_id: "jverce", account_id: "apn_kVh9AoD", }, }, { url: "https://api.example.com/users", options: { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ name: "John Doe" }), }, } );
v2.x (new)
// v2.x uses separate methods for each HTTP verb const response = await client.proxy.get({ externalUserId: "jverce", accountId: "apn_kVh9AoD", url: "https://api.example.com/data", headers: { Accept: "application/json", }, params: {}, // Additional query parameters if needed }); // POST request with body const postResponse = await client.proxy.post({ externalUserId: "jverce", accountId: "apn_kVh9AoD", url: "https://api.example.com/users", body: { name: "John Doe" }, // Body is passed as an object, not a string headers: { "Content-Type": "application/json", }, }); // Other HTTP methods are available await client.proxy.put({ /* ... */ }); await client.proxy.delete({ /* ... */ }); await client.proxy.patch({ /* ... */ });

Invoking workflows

v1.x (old)
// Invoke a workflow const response = await client.invokeWorkflow( "https://your-endpoint.m.pipedream.net", { foo: 123, bar: "abc", }, HTTPAuthType.OAuth // Optional auth type ); // Invoke a workflow for an external user const response = await client.invokeWorkflowForExternalUser( "https://your-workflow-url.m.pipedream.net", "jverce", // external user ID as second parameter { foo: 123, bar: "abc", } );
v2.x (new)
// Invoke a workflow const response = await client.workflows.invoke( { urlOrEndpoint: "https://your-endpoint.m.pipedream.net", body: { foo: 123, bar: "abc", }, headers: { Accept: "application/json", }, }, Pipedream.HTTPAuthType.OAuth ); // Invoke a workflow for an external user const response = await client.workflows.invokeForExternalUser({ urlOrEndpoint: "https://your-workflow-url.m.pipedream.net", externalUserId: "jverce", // now part of the options object body: { foo: 123, bar: "abc", }, });

Namespace mapping

Here's a complete list of how v1.x methods map to v2.x namespaced methods:

v1.x Methodv2.x Method
runAction()actions.run()
getAccounts()accounts.list()
getAccountById()accounts.retrieve()
deleteAccount()accounts.delete()
deleteAccountsByApp()Not available (use list + delete)
deleteExternalUser()users.delete()
createConnectToken()tokens.create()
validateConnectToken()tokens.validate()
deployTrigger()triggers.deploy()
getDeployedTriggers()deployedTriggers.list()
getDeployedTrigger()deployedTriggers.retrieve()
updateDeployedTrigger()deployedTriggers.update()
deleteDeployedTrigger()deployedTriggers.delete()
getTriggerEvents()deployedTriggers.listEvents()
getTriggerWebhooks()deployedTriggers.listWebhooks()
updateTriggerWebhooks()deployedTriggers.updateWebhooks()
getTriggerWorkflows()deployedTriggers.listWorkflows()
updateTriggerWorkflows()deployedTriggers.updateWorkflows()
getUsers()users.list()
getUser()users.retrieve()
getApps()apps.list()
getApp()apps.retrieve()
getComponents()components.list()
getComponent()components.retrieve()
configureComponent()components.configureProp()
reloadComponentProps()components.reloadProps()
getProjectInfo()projects.retrieve()
makeProxyRequest()proxy.get(), proxy.post(), etc.
invokeWorkflow()workflows.invoke()
invokeWorkflowForExternalUser()workflows.invokeForExternalUser()
rawAccessToken()rawAccessToken (getter property in server SDK)

New features in v2.x

The v2.x SDK includes several new features not available in v1.x:

Full TypeScript support

import { type RunActionResponse } from "@pipedream/sdk"; const result: RunActionResponse = await client.actions.run({ externalUserId: "jverce", id: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, });

Pagination support

// Automatic pagination for await (const account of client.accounts.list({ externalUserId: "jverce", })) { console.log(account); } // Manual pagination const firstPage = await client.accounts.list({ externalUserId: "jverce", limit: 20, }); if (firstPage.hasNextPage()) { const nextPage = await firstPage.getNextPage(); console.log(nextPage.data); }

Enhanced error handling

import { PipedreamError } from "@pipedream/sdk"; try { await client.actions.run({ externalUserId: "jverce", id: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, }); } catch (error) { if (error instanceof PipedreamError) { console.error("API Error:", error.status, error.message); } }

Request options

// Custom timeout const result = await client.actions.run( { externalUserId: "jverce", id: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, }, { timeoutInSeconds: 30, } ); // Retry configuration const result = await client.actions.run( { externalUserId: "jverce", id: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, }, { maxRetries: 3, } ); // Custom headers const result = await client.actions.run( { externalUserId: "jverce", id: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, }, { headers: { "X-Custom-Header": "value", }, } );

Abort signals

const controller = new AbortController(); // Abort after 5 seconds setTimeout(() => controller.abort(), 5000); try { const result = await client.actions.run( { externalUserId: "jverce", id: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, }, { abortSignal: controller.signal, } ); } catch (error) { if (error.name === "AbortError") { console.log("Request was aborted"); } }

Raw response access

const response = await client.actions .run({ externalUserId: "jverce", id: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, }) .withRawResponse(); console.log(response.data); // Parsed response data console.log(response.rawResponse); // Original Response object

Browser/Server Environment Separation

The v2.x SDK provides proper environment separation to ensure browser-safe imports without Node.js dependencies.

Package.json Export Structure

The SDK uses conditional exports to automatically serve the right code:

{ "exports": { ".": { "browser": "./dist/esm/browser/index.mjs", // Browser gets browser-only code "import": "./dist/esm/index.mjs", // Node.js gets full functionality "require": "./dist/cjs/index.js" }, "./browser": { "import": "./dist/esm/browser/index.mjs" // Explicit browser import }, "./server": { "import": "./dist/esm/index.mjs", // Explicit server import "require": "./dist/cjs/index.js" } } }

Import Recommendations

// For browser applications - avoids Node.js dependencies import { PipedreamClient, createFrontendClient } from "@pipedream/sdk/browser"; // For server applications - includes full functionality import { PipedreamClient } from "@pipedream/sdk/server"; // Automatic resolution (recommended for most cases) import { PipedreamClient } from "@pipedream/sdk";

This ensures:

  • Browser bundlers automatically get the browser-safe version
  • Node.js environments get the full SDK with all server functionality
  • Smaller bundle sizes for browser applications
  • No Node.js dependency errors in browser builds

Additional namespaces

The v2.x SDK includes several new namespaces not available in v1.x:

  • apps - Browse available apps and integrations
  • appCategories - List app categories
  • components - Work with components
  • deployedTriggers.listEvents() - List events for a deployed trigger
  • deployedTriggers.listWebhooks() - List webhooks for a deployed trigger
  • deployedTriggers.listWorkflows() - List workflows for a deployed trigger
  • projects - Get project information
  • proxy - Work with HTTP proxy endpoints
  • triggers - Additional trigger operations beyond deployment
  • users - User information
  • oauthTokens - OAuth token management
  • workflows - Invoke workflows

Partial migration

If you are unable to migrate all your code at once, you can use the new SDK alongside the old one by leveraging package aliases. This allows you to migrate incrementally without breaking your existing codebase. To do this, you can install the new SDK with an alias:

npm install @pipedream/sdk-v2@npm:@pipedream/sdk@^2.0.0 --save

Then, in your code, you can import the new SDK with the alias:

import { createBackendClient } from "@pipedream/sdk"; import { PipedreamClient } from "@pipedream/sdk-v2"; const clientOpts = { credentials: { clientId, clientSecret, }, projectId, environment, }; const client = createBackendClient(clientOpts); const newClient = new PipedreamClient({ ...clientOpts.credentials, projectEnvironment: clientOpts.environment, projectId: clientOpts.projectId, }); // Use old client for existing code const oldResult = await client.runAction({ externalUserId: "jverce", actionId: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, }); // Use new client for migrated code const newResult = await newClient.actions.run({ externalUserId: "jverce", id: "gitlab-list-commits", configuredProps: { gitlab: { authProvisionId: "apn_kVh9AoD" }, projectId: 45672541, refName: "main", }, });

Important removed functionality

Some methods from v1.x have been removed or changed significantly in v2.x:

  1. deleteAccountsByApp() - This bulk deletion method is no longer available. You'll need to list accounts for an app and delete them individually.

  2. rawAccessToken() - The method has been changed to a getter property. For the server-side SDK (Pipedream class from @pipedream/sdk/server or the wrapper), you can access the raw access token via the rawAccessToken getter property which returns a Promise:

    // v1.x (old) const token = await client.rawAccessToken(); // v2.x (new) const token = await client.rawAccessToken;

    For the base PipedreamClient class, token management is handled internally.

  3. Alternative method names - The v1.x SDK provided alternative method names (e.g., actionRun() as an alias for runAction()). These are no longer available in v2.x.

  4. userId parameter - The deprecated userId parameter has been removed. Always use externalUserId instead.

Migration checklist

  • Update import statements from createBackendClient/createFrontendClient to PipedreamClient.
  • Update client initialization to use new PipedreamClient() for both server-side and browser-side.
  • Convert all method calls to use namespaced format (e.g., client.actions.run()).
  • Keep parameter names in camelCase in your TypeScript/JavaScript code (the SDK handles conversion to snake_case automatically).
  • Pass externalUserId to methods instead of setting it on the client.
  • Update error handling to use PipedreamError type.
  • Review and implement new features like pagination and request options where beneficial.
  • Replace any usage of removed methods with their alternatives.
  • Update any code using rawAccessToken() - for server-side code, you can access client.rawAccessToken as a getter property that returns a Promise.
  • For raw response access, use .withRawResponse() method chaining instead of passing includeRawResponse option.
  • Test all migrated code thoroughly.
  • Remove the old SDK dependency once migration is complete.
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.