diff --git a/components/adp/adp.app.mjs b/components/adp/adp.app.mjs
index 626520486cc90..43cfad59ea0c3 100644
--- a/components/adp/adp.app.mjs
+++ b/components/adp/adp.app.mjs
@@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
-};
\ No newline at end of file
+};
diff --git a/components/danny_test_app/danny_test_app.app.mjs b/components/danny_test_app/danny_test_app.app.mjs
index 8141f60595dd6..18c3cebfa93a2 100644
--- a/components/danny_test_app/danny_test_app.app.mjs
+++ b/components/danny_test_app/danny_test_app.app.mjs
@@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
-};
\ No newline at end of file
+};
diff --git a/components/equifax/equifax.app.mjs b/components/equifax/equifax.app.mjs
index 560144a8ec1b3..e230f31e7f312 100644
--- a/components/equifax/equifax.app.mjs
+++ b/components/equifax/equifax.app.mjs
@@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
-};
\ No newline at end of file
+};
diff --git a/components/fiserv/fiserv.app.mjs b/components/fiserv/fiserv.app.mjs
index d966990507988..ed79ce5e839c8 100644
--- a/components/fiserv/fiserv.app.mjs
+++ b/components/fiserv/fiserv.app.mjs
@@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
-};
\ No newline at end of file
+};
diff --git a/components/grain/grain.app.mjs b/components/grain/grain.app.mjs
index 9aadcb84624b6..88edaa6e3e8ee 100644
--- a/components/grain/grain.app.mjs
+++ b/components/grain/grain.app.mjs
@@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
-};
\ No newline at end of file
+};
diff --git a/components/ibm_cloud_natural_language_understanding/ibm_cloud_natural_language_understanding.app.mjs b/components/ibm_cloud_natural_language_understanding/ibm_cloud_natural_language_understanding.app.mjs
index 392a93d4b5376..9b6cccb21bb6f 100644
--- a/components/ibm_cloud_natural_language_understanding/ibm_cloud_natural_language_understanding.app.mjs
+++ b/components/ibm_cloud_natural_language_understanding/ibm_cloud_natural_language_understanding.app.mjs
@@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
-};
\ No newline at end of file
+};
diff --git a/components/workflow_max/workflow_max.app.mjs b/components/workflow_max/workflow_max.app.mjs
index 803f6ffc43364..55595e2ee87f7 100644
--- a/components/workflow_max/workflow_max.app.mjs
+++ b/components/workflow_max/workflow_max.app.mjs
@@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
-};
\ No newline at end of file
+};
diff --git a/components/x_ai/x_ai.app.mjs b/components/x_ai/x_ai.app.mjs
index 43e6d5153b9c0..8488b4142f2fc 100644
--- a/components/x_ai/x_ai.app.mjs
+++ b/components/x_ai/x_ai.app.mjs
@@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
-};
\ No newline at end of file
+};
diff --git a/docs-v2/pages/connect/_meta.json b/docs-v2/pages/connect/_meta.json
index 6673166a10cb2..cbf54240a11bf 100644
--- a/docs-v2/pages/connect/_meta.json
+++ b/docs-v2/pages/connect/_meta.json
@@ -8,6 +8,9 @@
"quickstart": {
"title": "Quickstart"
},
+ "workflows": {
+ "title": "Running workflows"
+ },
"api": {
"title": "API & SDK Reference"
},
@@ -26,6 +29,9 @@
"connect-link": {
"title": "Connect Link"
},
+ "troubleshooting": {
+ "title": "Troubleshooting"
+ },
"customize-your-app": {
"title": "Customize Your App"
},
diff --git a/docs-v2/pages/connect/api.mdx b/docs-v2/pages/connect/api.mdx
index 408c477dd7333..bf3e90b1e7b10 100644
--- a/docs-v2/pages/connect/api.mdx
+++ b/docs-v2/pages/connect/api.mdx
@@ -55,8 +55,8 @@ import { createBackendClient } from "@pipedream/sdk";
// These secrets should be saved securely and passed to your environment
const pd = createBackendClient({
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
}
});
@@ -106,7 +106,7 @@ export default function Home() {
Some API endpoints accept an [environment](/connect/environments) parameter. This lets you specify the environment (`production` or `development`) where resources will live in your project.
-You can set the environment when you create the SDK client:
+Always set the environment when you create the SDK client:
```typescript
import { createBackendClient } from "@pipedream/sdk";
@@ -153,62 +153,7 @@ If you need higher rate limits, please [reach out](https://pipedream.com/support
### Invoke workflows
-You can use the SDK to invoke workflows on behalf of any end user. **Write one workflow, run it for all of your users**.
-
-
-
-```typescript
-import { createBackendClient, HTTPAuthType } from "@pipedream/sdk";
-
-// These secrets should be saved securely and passed to your environment
-const pd = createBackendClient({
- credentials: {
- clientId: "YOUR_CLIENT_ID",
- clientSecret: "YOUR_CLIENT_SECRET",
- },
-});
-
-await pd.invokeWorkflowForExternalUser(
- "enabc123", // pass the endpoint ID or full URL here
- "external_user_id", // The end user's ID in your system
- {
- method: "POST",
- body: {
- key: "value",
- }
- },
- HTTPAuthType.OAuth // Will automatically send the Authorization header with a fresh token
-)
-```
-
-
-```javascript
-import { createBackendClient } from "@pipedream/sdk";
-
-// These secrets should be saved securely and passed to your environment
-const pd = createBackendClient({
- credentials: {
- clientId: "YOUR_CLIENT_ID",
- clientSecret: "YOUR_CLIENT_SECRET",
- },
-});
-
-await pd.invokeWorkflowForExternalUser(
- "enabc123", // pass the endpoint ID or full URL here
- "external_user_id", // The end user's ID in your system
- {
- method: "POST",
- body: {
- key: "value",
- }
- },
- "oauth" // Will automatically send the Authorization header with a fresh token
-)
-```
-
-
-
-See the [workflow invocation docs](/workflows/triggers#oauth) for more details.
+You can use the SDK to [invoke workflows on behalf of any end user](/connect/workflows). **Write one workflow, run it for all of your users**.
### Tokens
@@ -252,12 +197,6 @@ When using [Connect Link](/connect/connect-link), you can optionally redirect yo
Pipedream will send events on successful auth, or any errors, to this URL via webhook. [See the webhooks docs](/connect/webhooks) for more information.
----
-
-`environment_name` **string** (_optional_)
-
-Specify the environment (`production` or `development`) to use for the account connection flow. Defaults to `production`.
-
##### Examples
To create a short-lived token via TypeScript / JavaScript SDK, you'll need to create a Pipedream API client and call the `createConnectToken` method. In our example app, this code is in `app/server.ts`.
@@ -277,14 +216,15 @@ import {
const pd = createBackendClient({
environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
const { token, expires_at } = await pd.createConnectToken({
- project_id: "your-project-id",
- external_user_id: "your-external-user-id" // The end user's ID in your system
+ project_id: "{your_project_id}",
+ external_user_id: "{your_external_user_id}" // The end user's ID in your system
});
```
@@ -295,14 +235,15 @@ import { createBackendClient } from "@pipedream/sdk";
const pd = createBackendClient({
environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
},
+ projectId: "{your_project_id}"
});
const { token, expires_at } = await pd.createConnectToken({
- project_id: "your-project-id",
- external_user_id: "your-external-user-id", // The end user's ID in your system
+ project_id: "{your_project_id}",
+ external_user_id: "{your_external_user_id}", // The end user's ID in your system
});
```
@@ -324,7 +265,7 @@ curl -X POST https://api.pipedream.com/v1/connect/{project_id}/tokens \
-H "X-PD-Environment: development" \
-H "Authorization: Bearer {access_token}" \
-d '{
- "external_user_id": "your-external-user-id"
+ "external_user_id": "{your_external_user_id}"
}'
```
@@ -382,10 +323,12 @@ import {
} from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
const accounts = await pd.getAccounts({
@@ -401,10 +344,12 @@ const accounts = await pd.getAccounts({
import { createBackendClient } from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
const accounts = await pd.getAccounts({
@@ -546,13 +491,15 @@ import {
} from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
-const account = await pd.getAccount(accountId, {
+const account = await pd.getAccountById(accountId, {
include_credentials: true, // set to true to include credentials
});
@@ -565,15 +512,17 @@ const account = await pd.getAccount(accountId, {
import { createBackendClient } from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
const accountId = "{account_id}"; // Replace with your account ID
-const account = await pd.getAccount(accountId, {
+const account = await pd.getAccountById(accountId, {
include_credentials: true, // set to true to include credentials
});
@@ -686,10 +635,12 @@ import {
} from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
await pd.deleteAccount(accountId);
@@ -702,10 +653,12 @@ await pd.deleteAccount(accountId);
import { createBackendClient } from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
await pd.deleteAccount(accountId);
@@ -766,10 +719,12 @@ import {
} from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
await pd.deleteAccountsByApp(appId);
@@ -782,10 +737,12 @@ await pd.deleteAccountsByApp(appId);
import { createBackendClient } from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
await pd.deleteAccount(accountId);
@@ -846,10 +803,12 @@ import {
} from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
await pd.deleteExternalUser(externalId);
@@ -862,10 +821,12 @@ console.log("All accounts associated with the external ID have been deleted.");
import { createBackendClient } from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
const externalId = "{external_user_id}"; // Replace with your external user ID
@@ -922,14 +883,16 @@ GET /{project_id}/info
import { createBackendClient } from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
const info = await pd.getProjectInfo({
- project_id: "your-project-id",
+ project_id: "{your_project_id}",
});
```
@@ -938,14 +901,16 @@ const info = await pd.getProjectInfo({
import { createBackendClient } from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
const info = await pd.getProjectInfo({
- project_id: "your-project-id",
+ project_id: "{your_project_id}",
});
```
diff --git a/docs-v2/pages/connect/environments.mdx b/docs-v2/pages/connect/environments.mdx
index a312c35c1ac54..1833ab99aac06 100644
--- a/docs-v2/pages/connect/environments.mdx
+++ b/docs-v2/pages/connect/environments.mdx
@@ -1,15 +1,17 @@
+import Callout from '@/components/Callout'
+
# Environments
Pipedream Connect projects support two environments: `development` and `production`.
1. Connected accounts and credentials stored in `development` remain separate from `production`.
-2. In `development`, you can use the official Pipedream OAuth apps, so you can test integrations without creating your own OAuth client.
+2. In `development`, you can use the official Pipedream OAuth clients, so you can test integrations without creating your own OAuth client, and you can also use features that are typically only available on higher paid tiers, like [running workflows on behalf of your end users](/connect/workflows).
## How to specify environment
You specify the environment when [creating a new Connect token](/connect/api/#create-a-new-token) with the Pipedream SDK or API. By default, the enviromment is set to `production`. When users succesfully connect their account, Pipedream saves it for that `external_user_id` in the specified environment.
-You can set the environment when you create the SDK client:
+Always set the environment when you create the SDK client:
```typescript
import { createBackendClient } from "@pipedream/sdk";
diff --git a/docs-v2/pages/connect/index.mdx b/docs-v2/pages/connect/index.mdx
index f0c722bd9fb53..1090173fb36ee 100644
--- a/docs-v2/pages/connect/index.mdx
+++ b/docs-v2/pages/connect/index.mdx
@@ -53,6 +53,12 @@ To view or delete your users' connected accounts:
You'll see a list of all users, their connected accounts, and the option to delete any accounts from the UI. You can also retrieve and delete all your users via the API ([see the docs for reference](/connect/api)).
+
+Connect currently supports one connected account per user / app / environment combination.
+
+So if user `abc-123` in your application connects their Slack account in `production`, then that same user connects a different Slack workspace (also in `production`), the first connected account will get overwritten in Pipedream and replaced by the second.
+
+
## Plans and pricing
**Connect is free to use for up to 1,000 connected accounts for any workspace**.
diff --git a/docs-v2/pages/connect/quickstart.mdx b/docs-v2/pages/connect/quickstart.mdx
index eb305fdd118fa..c37f30e755ff0 100644
--- a/docs-v2/pages/connect/quickstart.mdx
+++ b/docs-v2/pages/connect/quickstart.mdx
@@ -174,10 +174,12 @@ import {
} from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
async function getUserAccounts(external_user_id: string, include_credentials: boolean = false) {
@@ -198,10 +200,12 @@ import {
} from "@pipedream/sdk";
const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
credentials: {
- clientId: "your-oauth-client-id",
- clientSecret: "your-oauth-client-secret",
- }
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
});
async function getUserAccounts(external_user_id, include_credentials = false) {
diff --git a/docs-v2/pages/connect/tokens.mdx b/docs-v2/pages/connect/tokens.mdx
index b4dc1c03c3d33..4ffafc9ad03b1 100644
--- a/docs-v2/pages/connect/tokens.mdx
+++ b/docs-v2/pages/connect/tokens.mdx
@@ -1,4 +1,6 @@
-# Connect Tokens
+import Callout from '@/components/Callout'
+
+# Connect tokens
When you initiate account connection for your end users, you must either:
@@ -9,6 +11,10 @@ Here, we'll show you how to generate tokens for your users and return that to yo
Use tokens when you want to handle the account connection flow yourself, in your app's UI. For example, you might want to show a **Connect Slack** button in your app that triggers the account connection flow for Slack, or launch the flow in a modal.
+
+Connect tokens currently have a 4-hour expiry, and can only be used once.
+
+
## Creating a token
See docs on [the `/tokens` endpoint](/connect/api/#create-a-new-token) to create new tokens.
@@ -21,6 +27,6 @@ When you generate a token, you can specify a `webhook_uri` where Pipedream will
## Tokens are scoped to end users and project environments
-When you [create a new Connect token](/connect/api/#create-a-new-token), you pass an `external_user_id` and an optional `environment_name` parameter. By default, the environment is set to `production`. See the docs on [environments](/connect/environments) for more information.
+When you [create a new Connect token](/connect/api/#create-a-new-token), you pass an `external_user_id` and an `environment`. See the docs on [environments](/connect/environments) for more information on passing environment in the SDK and API.
-Tokens are scoped to this user and environment. When the user successfully connects an account with that token, it will be saved for that `external_user_id` in the specified `environment_name`.
+Tokens are scoped to this user and environment. When the user successfully connects an account with that token, it will be saved for that `external_user_id` in the specified environment.
diff --git a/docs-v2/pages/connect/troubleshooting.mdx b/docs-v2/pages/connect/troubleshooting.mdx
new file mode 100644
index 0000000000000..8a81d5195f990
--- /dev/null
+++ b/docs-v2/pages/connect/troubleshooting.mdx
@@ -0,0 +1,45 @@
+# Troubleshooting
+
+Below are some common errors when connecting your users' accounts via Pipedream Connect.
+
+### Error creating a Connect token
+
+_Error creating token: Error: Failed to obtain OAuth token: Response Error: 401 Unauthorized_
+
+Authorization to the Pipedream API failed when creating the Connect token. Double-check the client ID or secret for your [Pipedream OAuth client](/connect/api#authentication).
+
+### Error connecting an account
+
+Most errors when connecting an account are related to the [Connect token](/connect/tokens), which Pipedream validates from the Connect iFrame.
+
+#### Possible errors
+
+_This link has expired. Please request a new one from the app developer._
+
+_This session has expired. Please refresh the page to try again._
+
+#### Troubleshooting steps
+
+Pipedream typically returns an explicit error message in the HTTP response of the token validation network call directly from the iFrame in the client. To check for errors, start the account connection flow in a browser and open the developer console to view the network requests.
+
+Filter for requests to
+
+```
+https://api.pipedream.com/v1/connect/tokens
+```
+
+and check the response for error messages.
+
+#### Token validation errors
+
+_The Pipedream Connect token is invalid. Please generate a new one and try again._
+
+Connect tokens expire, and are only able to be used once. Try generating a new token and try again.
+
+_App not found. Please check your app id._
+
+Double-check the app slug you're passing [when connecting your user's account](/connect/quickstart#connect-a-users-account).
+
+### Connection failed. Please retry or contact support.
+
+The user may have closed the OAuth popup window without completing authorization.
\ No newline at end of file
diff --git a/docs-v2/pages/connect/workflows.mdx b/docs-v2/pages/connect/workflows.mdx
new file mode 100644
index 0000000000000..de41d24ae06ba
--- /dev/null
+++ b/docs-v2/pages/connect/workflows.mdx
@@ -0,0 +1,217 @@
+import { Steps, Tabs } from 'nextra/components'
+import ArcadeEmbed from '@/components/ArcadeEmbed'
+import Callout from '@/components/Callout'
+import Image from 'next/image'
+
+# Running workflows for your end users
+
+Just like you can build and run internal [workflows](/workflows/) for your team, **you can run workflows for [your end users](/connect/api#external-users), too**.
+
+Whether you're building well-defined integrations or more-autonomous AI agents, workflows provide a powerful set of tools for running [code](/code) or [pre-defined actions](/workflows/actions) on behalf of your users. Pipedream's UI makes it easy to build, test, and [debug](/workflows/inspect) workflows.
+
+## What are workflows?
+
+
+

+
+
+Workflows are sequences of [steps](/workflows/steps) [triggered by an event](/workflows/triggers), like an HTTP request, or new rows in a Google sheet.
+
+You can use [pre-built actions](/workflows/actions/) or custom [Node.js](/code/nodejs/), [Python](/code/python/), [Golang](/code/go/), or [Bash](/code/bash/) code in workflows and connect to any of our {process.env.PUBLIC_APPS} integrated apps.
+
+Workflows also have built-in:
+
+- [Flow control](/workflows/control-flow)
+- [Concurrency and throttling](/workflows/concurrency-and-throttling)
+- [Key-value stores](/data-stores)
+- [Error handling](/workflows/errors)
+- [VPCs](/workflows/vpc)
+- [And more](https://pipedream.com/pricing)
+
+Read [the quickstart](/quickstart/) to learn more.
+
+## How to run workflows for your end users
+
+
+
+### Create an OAuth client
+
+**This step is optional but strongly recommended.** To securely run workflows for end users, you'll need to first [create a Pipedream OAuth client](/rest-api/auth#creating-an-oauth-client). Pipedream uses OAuth to authenticate requests to the Pipedream API and workflows.
+
+
+### Create a workflow
+
+[Create a new workflow](/workflows#how-do-i-create-a-new-workflow) or open an existing one.
+
+### Add an HTTP trigger, configure OAuth
+
+1. Add an [HTTP trigger](/workflows/triggers#http) to your workflow.
+2. [Configure **OAuth** authorization](/workflows/triggers#oauth) on the trigger. Again, this step is optional **but strongly recommended.**
+
+### Configure accounts to use your end users' auth
+
+When you configure [pre-built actions](/workflows/actions) or [custom code that connects to third-party APIs](/code/nodejs/auth), you can link accounts in one of two ways:
+
+1. **Use your own account**: If you're connecting to an API that uses your own API key or developer account — for example, a workflow that connects to the OpenAI API or a PostgreSQL database — click the **Connect account** button to link your own, static account.
+
+
+

+
+
+2. **Use your end users' auth**: If you're building a workflow that connects to your end users' accounts — for example, a workflow that sends a message with your user's Slack account — you can select the option to **Use end user's auth via Connect**:
+
+
+

+
+
+When you trigger the workflow, Pipedream will look up the corresponding account for the end user whose user ID you provide [when invoking the workflow](#invoke-the-workflow).
+
+### Connect a test account
+
+To run an end-to-end test as an end user, you need to have users and connected accounts in your project. If you already have a **development** account linked, you can skip this step.
+
+If you don't, the fastest way to do this is [on the **Users** tab](/connect#users) in your Pipedream project:
+- You'll see there's a button to **Connect account**
+- Go through the flow and make sure to create the account in **development** mode
+- Note the **external user ID** of the account you just connected, you'll need it in the next step
+
+
+
+
+### Generate a test request
+
+Test events are critical for developing workflows effectively. Without a test event, you won't be able to test your workflow end to end in the builder, see the shape of the event data that triggers the workflow, and the lookup to use your end user's auth won't work.
+
+To generate a test event, click **Send Test Event** in the trigger, and fill in the event data. This will trigger the workflow and allow you to test the workflow end to end in the builder.
+
+
+Make sure to include these headers in your test request:
+- `x-pd-environment: development`
+- `x-pd-external-user-id: {your_external_user_id}`
+
+
+
+
+
+
+### Deploy your workflow
+
+When you're done with the workflow, click **Deploy** at the top right.
+
+### Invoke the workflow
+
+If you're using TypeScript or a JavaScript runtime, [install the Pipedream SDK](/connect/api#installing-the-typescript-sdk). Pipedream also provides an HTTP API for invoking workflows (see example below).
+
+```bash
+npm i @pipedream/sdk
+```
+
+To invoke workflows, you'll need:
+
+1. The OAuth client ID and secret from **[Step 1](/connect/workflows#create-an-oauth-client)**
+2. Your [Project ID](/projects#finding-your-projects-id)
+3. Your workflow's HTTP endpoint URL
+4. The [external user ID](/connect/api#external-users) of the user you'd like to run the workflow for
+5. The [Connect environment](/connect/environments) tied to the user's account
+
+Then invoke the workflow like so:
+
+
+
+```typescript
+import { createBackendClient, HTTPAuthType } from "@pipedream/sdk";
+
+// These secrets should be saved securely and passed to your environment
+const pd = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
+ credentials: {
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
+ },
+ projectId: "{your_project_id}"
+});
+
+await pd.invokeWorkflowForExternalUser(
+ "{your_endpoint_url}", // pass the endpoint ID or full URL here
+ "{your_external_user_id}" // The end user's ID in your system
+ {
+ method: "POST",
+ body: {
+ message: "Hello World"
+ }
+ },
+ HTTPAuthType.OAuth // Will automatically send the Authorization header with a fresh token
+)
+```
+
+
+```javascript
+import { createBackendClient } from "@pipedream/sdk";
+
+// These secrets should be saved securely and passed to your environment
+const client = createBackendClient({
+ environment: "development", // change to production if running for a test production account, or in production
+ credentials: {
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}"
+ },
+ projectId: "{your_project_id}"
+});
+
+const response = await client.invokeWorkflowForExternalUser(
+ "{your_endpoint_url}", // pass the endpoint ID or full URL here
+ "{your_external_user_id}" // The end user's ID in your system
+ {
+ method: "POST",
+ body: {
+ message: "Hello World"
+ }
+ }
+)
+```
+
+
+```bash
+# First, obtain an OAuth access token
+curl -X POST https://api.pipedream.com/v1/oauth/token \
+ -H "Content-Type: application/json" \
+ -d '{
+ "grant_type": "client_credentials",
+ "client_id": "{oauth_client_id}",
+ "client_secret": "{oauth_client_secret}"
+ }'
+
+# The response will include an access_token. Use it in the Authorization header below.
+
+curl -X POST https://{your-endpoint-url} \
+ -H "Content-Type: application/json" \
+ -H "Authorization: Bearer {access_token}" \
+ -H 'X-PD-External-User-ID: {your_external_user_id}' \
+ -H 'X-PD-Environment: development' \ # 'development' or 'production'
+ -d '{
+ "message": "Hello, world"
+ }'
+```
+
+
+
+
+## Errors
+
+#### No external user ID passed, but one or more steps require it
+- One or more steps in the workflow are configured to **Use end user's auth via Connect**, but no external user ID was passed when invoking the workflow.
+- [Refer to the docs](#invoke-the-workflow) to make sure you're passing external user ID correctly when invoking the workflow.
+
+#### No matching external user ID
+- There was an external user ID passed, but it didn't match any users in the project.
+- Double-check that the external user ID that you passed when invoking the workflow matches one either [in the UI](/connect#users) or [via the API](/connect/api#accounts).
+
+#### Required account not found for external user ID
+- The external user ID was passed when invoking the workflow, but the user doesn't have a connected account for one or more of the apps that are configured to use it in this workflow execution.
+- You can check which connected accounts are available for that user [in the UI](/connect#users) or [via the API](/connect/api#accounts).
+
+#### Running workflows for your users in production requires a higher tier plan
+- Anyone is able to run workflows for your end users in `development`. The Business plan is required to run on behalf of `production` users.
+- Schedule a call with our sales team and learn more about pricing [here](https://pipedream.com/pricing?plan=Enterprise).
\ No newline at end of file
diff --git a/docs-v2/pages/rest-api/index.mdx b/docs-v2/pages/rest-api/index.mdx
index 6337444fde7b0..8644832aa8f7a 100644
--- a/docs-v2/pages/rest-api/index.mdx
+++ b/docs-v2/pages/rest-api/index.mdx
@@ -684,7 +684,7 @@ Pass `debug=true` to return additional data in the response, useful for inspecti
#### Example Request
```shell
-curl https://api.pipedream.com/v1/components/search\?query\="When someone sends a tweet mentioning my brand, send me an SMS" \
+curl https://api.pipedream.com/v1/components/search\?query\="When a new Hubspot contact is added, send me an SMS"&limit=1 \
-H "Authorization: Bearer " \
-H "Content-Type: application/json"
```
@@ -694,14 +694,10 @@ curl https://api.pipedream.com/v1/components/search\?query\="When someone sends
```json
{
"sources": [
- "twitter-new-mention-received-by-user",
- "twitter-new-tweet-posted-by-user",
- "twitter-new-tweet-posted-matching-query"
+ "hubspot-new-contact"
],
"actions": [
- "sms-send-sms",
- "sms_fusion-send-sms",
- "sms_alert-send-sms"
+ "twilio-send-sms"
]
}
```
diff --git a/docs-v2/pages/workflows/index.mdx b/docs-v2/pages/workflows/index.mdx
index e13914b644599..5515ade0a3c77 100644
--- a/docs-v2/pages/workflows/index.mdx
+++ b/docs-v2/pages/workflows/index.mdx
@@ -4,7 +4,7 @@ import VideoPlayer from '@/components/VideoPlayer';
-Workflows make it easy to integrate your apps, data, and APIs - all with no servers or infrastructure to manage. They're sequences of linear [steps](/workflows/steps) [triggered by an event](/workflows/triggers), like an HTTP request, or new rows in a Google sheet.
+Workflows make it easy to integrate your apps, data, and APIs - all with no servers or infrastructure to manage. They're sequences of [steps](/workflows/steps) [triggered by an event](/workflows/triggers), like an HTTP request, or new rows in a Google sheet.
You can use [pre-built actions](/workflows/actions/) or custom [Node.js](/code/nodejs/), [Python](/code/python/), [Golang](/code/go/), or [Bash](/code/bash/) code in workflows and connect to any of our {process.env.PUBLIC_APPS} integrated apps.
diff --git a/docs-v2/pages/workflows/triggers.mdx b/docs-v2/pages/workflows/triggers.mdx
index 7b97886f6993d..1a7c0a3b3a246 100644
--- a/docs-v2/pages/workflows/triggers.mdx
+++ b/docs-v2/pages/workflows/triggers.mdx
@@ -141,9 +141,9 @@ When making HTTP requests, pass the OAuth access token as a `Bearer` token in th
curl -H 'Authorization: Bearer ' https://myendpoint.m.pipedream.net
```
-You can use the Pipedream SDK to automatically refresh access tokens and invoke workflows:
+You can use the Pipedream SDK to automatically refresh access tokens and invoke workflows, or make HTTP requests directly to the workflow's URL:
-
+
```typescript
import { createBackendClient, HTTPAuthType } from "@pipedream/sdk";
@@ -151,8 +151,8 @@ import { createBackendClient, HTTPAuthType } from "@pipedream/sdk";
// These secrets should be saved securely and passed to your environment
const pd = createBackendClient({
credentials: {
- clientId: "YOUR_CLIENT_ID",
- clientSecret: "YOUR_CLIENT_SECRET",
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
},
});
@@ -175,8 +175,8 @@ import { createBackendClient } from "@pipedream/sdk";
// These secrets should be saved securely and passed to your environment
const pd = createBackendClient({
credentials: {
- clientId: "YOUR_CLIENT_ID",
- clientSecret: "YOUR_CLIENT_SECRET",
+ clientId: "{oauth_client_id}",
+ clientSecret: "{oauth_client_secret}",
},
});
@@ -192,6 +192,27 @@ await pd.invokeWorkflow(
)
```
+
+```bash
+# First, obtain an OAuth access token
+curl -X POST https://api.pipedream.com/v1/oauth/token \
+ -H "Content-Type: application/json" \
+ -d '{
+ "grant_type": "client_credentials",
+ "client_id": "{oauth_client_id}",
+ "client_secret": "{oauth_client_secret}"
+ }'
+
+# The response will include an access_token. Use it in the Authorization header below.
+
+curl -X POST https://{your-endpoint-url} \
+ -H "Content-Type: application/json" \
+ -H "Authorization: Bearer {access_token}" \
+ -d '{
+ "message": "Hello, world"
+ }'
+```
+