# Changelog Source: https://www.activepieces.com/docs/about/changelog A log of all notable changes to Activepieces # i18n Translations Source: https://www.activepieces.com/docs/about/i18n This guide helps you understand how to change or add new translations. Activepieces uses Crowdin because it helps translators who don't know how to code. It also makes the approval process easier. Activepieces automatically sync new text from the code and translations back into the code. ## Contribute to existing translations 1. Create Crowdin account 2. Join the project [https://crowdin.com/project/activepieces](https://crowdin.com/project/activepieces) Join Project 3. Click on the language you want to translate 4. Click on "Translate All" Translate All 5. Select Strings you want to translate and click on "Save" button ## Adding a new language * Please contact us ([support@activepieces.com](mailto:support@activepieces.com)) if you want to add a new language. We will add it to the project and you can start translating. # License Source: https://www.activepieces.com/docs/about/license Activepieces' **core** is released as open source under the [MIT license](https://github.com/activepieces/activepieces/blob/main/LICENSE) and enterprise / cloud editions features are released under [Commercial License](https://github.com/activepieces/activepieces/blob/main/packages/ee/LICENSE) The MIT license is a permissive license that grants users the freedom to use, modify, or distribute the software without any significant restrictions. The only requirement is that you include the license notice along with the software when distributing it. Using the enterprise features (under the packages/ee and packages/server/api/src/app/ee folder) with a self-hosted instance requires an Activepieces license. If you are looking for these features, contact us at [sales@activepieces.com](mailto:sales@activepieces.com). **Benefits of Dual Licensing Repo** * **Transparency** - Everyone can see what we are doing and contribute to the project. * **Clarity** - Everyone can see what the difference is between the open source and commercial versions of our software. * **Audit** - Everyone can audit our code and see what we are doing. * **Faster Development** - We can develop faster and more efficiently. If you are still confused or have feedback, please open an issue on GitHub or send a message in the #contribution channel on Discord. # Override OAuth2 Apps Source: https://www.activepieces.com/docs/admin-guide/guides/manage-oauth2 Use your own OAuth2 credentials instead of the default Activepieces apps ## Default Behavior When users connect to services like Google Sheets or Slack, they see "Activepieces" as the app requesting access. This works out of the box with no setup required. ## Why Replace OAuth2 Apps? * **Branding**: Show your company name instead of "Activepieces" in authorization screens * **Higher Limits**: Some services have stricter rate limits for shared OAuth apps * **Compliance**: Your organization may require using company-owned credentials ## How to Configure 1. Go to **Platform Admin → Setup → Pieces** 2. Find the piece you want to configure (e.g., Google Sheets) 3. Click the lock icon to open the OAuth2 settings 4. Enter your own Client ID and Client Secret Manage Oauth2 apps # How to Manage Pieces Source: https://www.activepieces.com/docs/admin-guide/guides/manage-pieces Control which integrations are available to your users ## Overview **Pieces** are the building blocks of Activepieces — they are integrations and connectors (like Google Sheets, Slack, OpenAI, etc.) that users can use in their automation flows. As a platform administrator, you have full control over which pieces are available to your users. This allows you to: * **Enforce security policies** by restricting access to certain integrations * **Simplify the user experience** by showing only relevant pieces for your use case * **Deploy custom/private pieces** that are specific to your organization There are **two levels** of piece management: | Level | Who Can Manage | Scope | | ------------------ | -------------- | --------------------------------------------- | | **Platform Level** | Platform Admin | Install and remove across the entire platform | | **Project Level** | Project Admin | Show/hide specific pieces for specfic project | *** ## Platform-Level Management Platform administrators can manage pieces for the entire Activepieces instance from **Platform Admin → Setup → Pieces**. ## Project-Level Management Project administrators can further restrict which pieces are available within their specific project. This is useful when different teams or projects need access to different integrations. ### Show/Hide Pieces in a Project Navigate to your project and go to **Settings → Pieces**. You'll see a list of all pieces installed on the platform. Toggle the visibility for each piece: * **Enabled**: Users in this project can use the piece * **Disabled**: The piece is hidden from users in this project Changes take effect immediately — users will only see the enabled pieces when building their flows. Manage Pieces Manage Pieces Project-level settings can only **hide** pieces that are installed at the platform level. You cannot add pieces at the project level that aren't already installed on the platform. ### Install Private Pieces For detailed instructions on building custom pieces, check the [Building Pieces](/build-pieces/building-pieces/overview) documentation. If you've built a custom piece for your organization, you can upload it directly as a tarball (`.tgz`) file. Build your piece using the Activepieces CLI: ```bash theme={null} npm run pieces -- build --name=your-piece-name ``` This generates a tarball in `dist/packages/pieces/your-piece-name`. Go to **Platform Admin → Setup → Pieces** and click **Install Piece**. Choose **Upload File** as the installation source. Select the `.tgz` file from your build output and upload it. Install Piece # Manage User Roles Source: https://www.activepieces.com/docs/admin-guide/guides/permissions Documentation on project permissions in Activepieces Activepieces utilizes Role-Based Access Control (RBAC) for managing permissions within projects. Each project consists of multiple flows and users, with each user assigned specific roles that define their actions within the project. ## Default Roles Activepieces comes with four standard roles out of the box. The table below shows the permissions for each role: | Permission | Admin | Editor | Operator | Viewer | | -------------------------- | :---: | :----: | :------: | :----: | | **Flows** | | | | | | View Flows | ✓ | ✓ | ✓ | ✓ | | Edit Flows | ✓ | ✓ | | | | Publish / Toggle Flows | ✓ | ✓ | ✓ | | | **Runs** | | | | | | View Runs | ✓ | ✓ | ✓ | ✓ | | Retry Runs | ✓ | ✓ | ✓ | | | **Connections** | | | | | | View Connections | ✓ | ✓ | ✓ | ✓ | | Edit Connections | ✓ | ✓ | ✓ | | | **Team** | | | | | | View Project Members | ✓ | ✓ | ✓ | ✓ | | Add/Remove Project Members | ✓ | | | | | **Git Sync** | | | | | | Configure Git Repo | ✓ | | | | | Pull Flows from Git | ✓ | | | | | Push Flows to Git | ✓ | | | | ## Custom Roles If the default roles don't fit your needs, you can create custom roles with specific permissions. Go to **Platform Admin** → **Security** → **Project Roles** Click **Create Role** and give it a name Select the specific permissions you want to grant to this role Custom roles are useful when you need fine-grained control, such as allowing users to view and retry runs without being able to edit flows. # Setup AI Providers Source: https://www.activepieces.com/docs/admin-guide/guides/setup-ai-providers AI providers are configured by the platform admin to centrally manage credentials and access, making [AI pieces](https://www.activepieces.com/pieces/ai) and their features available to everyone in all projects. ## Supported Providers * **OpenAI** * **Anthropic** * **Gemini** * **Vercel AI Gateway** * **Cloudflare AI Gateway** ## How to Setup Go to **Admin Console** → **AI** page. Add your provider's base URL and API key. These settings apply to all projects. Manage AI Providers ## Cost Control & Logging Use an AI gateway like **Vercel AI Gateway** or **Cloudflare AI Gateway** to: * Set rate limits and budgets * Log and monitor all AI requests * Track usage across projects Just set the gateway URL as your provider's base URL in the Admin Console. # How to Setup SSO Source: https://www.activepieces.com/docs/admin-guide/guides/sso Configure Single Sign-On (SSO) to enable secure, centralized authentication for your Activepieces platform ## Overview Single Sign-On (SSO) allows your team to authenticate using your organization's existing identity provider, eliminating the need for separate Activepieces credentials. This improves security, simplifies user management, and provides a seamless login experience. ## Prerequisites Before configuring SSO, ensure you have: * **Admin access** to your Activepieces platform * **Admin access** to your identity provider (Google, GitHub, Okta, or JumpCloud) * The **redirect URL** from your Activepieces SSO configuration screen ## Accessing SSO Configuration Navigate to **Platform Settings** → **SSO** in your Activepieces admin dashboard to access the SSO configuration screen. SSO Configuration ## Enforcing SSO You can enforce SSO by specifying your organization's email domain. When SSO enforcement is enabled: * Users with matching email domains must authenticate through the SSO provider * Email/password login can be disabled for enhanced security * All authentication is routed through your designated identity provider We recommend testing SSO with a small group of users before enforcing it organization-wide. ## Supported SSO Providers Activepieces supports multiple SSO providers to integrate with your existing identity management system. ### Google Go to the [Google Cloud Console](https://console.cloud.google.com/) and select your project (or create a new one). Navigate to **APIs & Services** → **Credentials** → **Create Credentials** → **OAuth client ID**. Select **Web application** as the application type. Copy the **Redirect URL** from the Activepieces SSO configuration screen and add it to the **Authorized redirect URIs** in Google Cloud Console. Copy the **Client ID** and **Client Secret** from Google and paste them into the corresponding fields in Activepieces. Click **Finish** to complete the setup. ### GitHub Go to [GitHub Developer Settings](https://github.com/settings/developers) → **OAuth Apps** → **New OAuth App**. Fill in the application details: * **Application name**: Choose a recognizable name (e.g., "Activepieces SSO") * **Homepage URL**: Enter your Activepieces instance URL Copy the **Redirect URL** from the Activepieces SSO configuration screen and paste it into the **Authorization callback URL** field. Click **Register application** to create the OAuth App. After registration, click **Generate a new client secret** and copy it immediately (it won't be shown again). Copy the **Client ID** and **Client Secret** and paste them into the corresponding fields in Activepieces. Click **Finish** to complete the setup. ### SAML with Okta Go to the [Okta Admin Portal](https://login.okta.com/) → **Applications** → **Create App Integration**. Choose **SAML 2.0** as the sign-on method and click **Next**. Enter an **App name** (e.g., "Activepieces") and optionally upload a logo. Click **Next**. * **Single sign-on URL**: Copy the SSO URL from the Activepieces configuration screen * **Audience URI (SP Entity ID)**: Enter `Activepieces` * **Name ID format**: Select `EmailAddress` Add the following attribute mappings: | Name | Value | | ----------- | ---------------- | | `firstName` | `user.firstName` | | `lastName` | `user.lastName` | | `email` | `user.email` | Click **Next**, select the appropriate feedback option, and click **Finish**. Go to the **Sign On** tab → **View SAML setup instructions** or **View IdP metadata**. Copy the Identity Provider metadata XML. * Paste the **IdP Metadata** XML into the corresponding field * Copy the **X.509 Certificate** from Okta and paste it into the **Signing Key** field Click **Save** to complete the setup. ### SAML with JumpCloud Go to the [JumpCloud Admin Portal](https://console.jumpcloud.com/) → **SSO Applications** → **Add New Application** → **Custom SAML App**. Copy the **ACS URL** from the Activepieces configuration screen and paste it into the **ACS URLs** field in JumpCloud. JumpCloud ACS URL Set the **SP Entity ID** (Audience URI) to `Activepieces`. Configure the following attribute mappings: | Service Provider Attribute | JumpCloud Attribute | | -------------------------- | ------------------- | | `firstName` | `firstname` | | `lastName` | `lastname` | | `email` | `email` | JumpCloud User Attributes JumpCloud does not include the `HTTP-Redirect` binding by default. You **must** enable this option. JumpCloud Redirect Binding Without HTTP-Redirect binding, the SSO integration will not work correctly. Click **Save**, then refresh the page and click **Export Metadata**. JumpCloud Export Metadata Verify that the exported XML contains `Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"` to ensure the binding was properly enabled. Paste the exported metadata XML into the **IdP Metadata** field in Activepieces. Locate the `` element in the IdP metadata and extract its value. Format it as a PEM certificate: ``` -----BEGIN CERTIFICATE----- [PASTE THE CERTIFICATE VALUE HERE] -----END CERTIFICATE----- ``` Paste this into the **Signing Key** field. In JumpCloud, assign the application to the appropriate users or user groups. JumpCloud Assign App Click **Finish** to complete the setup. ## Troubleshooting * Verify the redirect URL is correctly configured in your identity provider * Ensure users are assigned to the application in your identity provider * Check that email domains match the SSO enforcement settings * Confirm the IdP metadata is complete and correctly formatted * Verify the signing certificate is properly formatted with BEGIN/END markers * Ensure all required attributes (firstName, lastName, email) are mapped * Enable the HTTP-Redirect binding option in JumpCloud * Re-export the metadata after enabling the binding * Verify the binding appears in the exported XML ## Need Help? If you encounter issues during SSO setup, please contact our enterprise support or [sales team](https://www.activepieces.com/sales). # How to Structure Projects Source: https://www.activepieces.com/docs/admin-guide/guides/structure-projects Projects in Activepieces are the main units for organizing your automations and resources within your organization. Every project contains its own flows, connections, and tables. Access to these resources is shared among everyone who has access to that project. There are two types of projects: * **Personal Projects**: Each user invited to your organization automatically receives a personal project. This is a private space where only that user can create and manage flows, connections, and tables. * **Team Projects**: Team projects are shared spaces that can be created and managed from this page. Multiple users can be invited to a team project, allowing them to collaborate, share access to flows, connections, and tables, and work together. When organizing your work, create team projects for group collaboration and utilize personal projects for individual or private tasks. # Connection Deleted Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/connection-deleted # Connection Upserted Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/connection-upserted # Flow Created Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/flow-created # Flow Deleted Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/flow-deleted # Flow Run Finished Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/flow-run-finished # Flow Run Started Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/flow-run-started # Flow Updated Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/flow-updated # Folder Created Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/folder-created # Folder Deleted Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/folder-deleted # Folder Updated Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/folder-updated # Overview Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/overview This table in admin console contains all application events. We are constantly adding new events, so there is no better place to see the events defined in the code than [here](https://github.com/activepieces/activepieces/blob/main/packages/ee/shared/src/lib/audit-events/index.ts). Audit Logs # Signing Key Created Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/signing-key-created # User Email Verified Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/user-email-verified # User Password Reset Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/user-password-reset # User Signed In Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/user-signed-in # User Signed Up Source: https://www.activepieces.com/docs/admin-guide/security/audit-logs/user-signed-up # Security & Data Practices Source: https://www.activepieces.com/docs/admin-guide/security/practices We prioritize security and follow these practices to keep information safe. ## External Systems Credentials **Storing Credentials** All credentials are stored with 256-bit encryption keys, and there is no API to retrieve them for the user. They are sent only during processing, after which access is revoked from the engine. **Data Masking** We implement a robust data masking mechanism where third-party credentials or any sensitive information are systematically censored within the logs, guaranteeing that sensitive information is never stored or documented. **OAuth2** Integrations with third parties are always done using OAuth2, with a limited number of scopes when third-party support allows. ## Vulnerability Disclosure Activepieces is an open-source project that welcomes contributors to test and report security issues. For detailed information about our security policy, please refer to our GitHub Security Policy at: [https://github.com/activepieces/activepieces/security/policy](https://github.com/activepieces/activepieces/security/policy) ## Access and Authentication **Role-Based Access Control (RBAC)** To manage user access, we utilize Role-Based Access Control (RBAC). Team admins assign roles to users, granting them specific permissions to access and interact with projects, folders, and resources. RBAC allows for fine-grained control, enabling administrators to define and enforce access policies based on user roles. **Single Sign-On (SSO)** Implementing Single Sign-On (SSO) serves as a pivotal component of our security strategy. SSO streamlines user authentication by allowing them to access Activepieces with a single set of credentials. This not only enhances user convenience but also strengthens security by reducing the potential attack surface associated with managing multiple login credentials. **Audit Logs** We maintain comprehensive audit logs to track and monitor all access activities within Activepieces. This includes user interactions, system changes, and other relevant events. Our meticulous logging helps identify security threats and ensures transparency and accountability in our security measures. **Password Policy Enforcement** Users log in to Activepieces using a password known only to them. Activepieces enforces password length and complexity standards. Passwords are not stored; instead, only a secure hash of the password is stored in the database. For more information. ## Privacy & Data **Supported Cloud Regions** Presently, our cloud services are available in Germany as the supported data region. We have plans to expand to additional regions in the near future. If you opt for **self-hosting**, the available regions will depend on where you choose to host. **Policy** To better understand how we handle your data and prioritize your privacy, please take a moment to review our [Privacy Policy](https://www.activepieces.com/privacy). This document outlines in detail the measures we take to safeguard your information and the principles guiding our approach to privacy and data protection. # Create Action Source: https://www.activepieces.com/docs/build-pieces/building-pieces/create-action ## Action Definition Now let's create first action which fetch random ice-cream flavor. ```bash theme={null} npm run cli actions create ``` You will be asked three questions to define your new piece: 1. `Piece Folder Name`: This is the name associated with the folder where the action resides. It helps organize and categorize actions within the piece. 2. `Action Display Name`: The name users see in the interface, conveying the action's purpose clearly. 3. `Action Description`: A brief, informative text in the UI, guiding users about the action's function and purpose. Next, Let's create the action file: **Example:** ```bash theme={null} npm run cli actions create ? Enter the piece folder name : gelato ? Enter the action display name : get icecream flavor ? Enter the action description : fetches random icecream flavor. ``` This will create a new TypeScript file named `get-icecream-flavor.ts` in the `packages/pieces/community/gelato/src/lib/actions` directory. Inside this file, paste the following code: ```typescript theme={null} import { createAction, Property, PieceAuth, } from '@activepieces/pieces-framework'; import { httpClient, HttpMethod } from '@activepieces/pieces-common'; import { gelatoAuth } from '../..'; export const getIcecreamFlavor = createAction({ name: 'get_icecream_flavor', // Must be a unique across the piece, this shouldn't be changed. auth: gelatoAuth, displayName: 'Get Icecream Flavor', description: 'Fetches random icecream flavor', props: {}, async run(context) { const res = await httpClient.sendRequest({ method: HttpMethod.GET, url: 'https://cloud.activepieces.com/api/v1/webhooks/RGjv57ex3RAHOgs0YK6Ja/sync', headers: { Authorization: context.auth, // Pass API key in headers }, }); return res.body; }, }); ``` The createAction function takes an object with several properties, including the `name`, `displayName`, `description`, `props`, and `run` function of the action. The `name` property is a unique identifier for the action. The `displayName` and `description` properties are used to provide a human-readable name and description for the action. The `props` property is an object that defines the properties that the action requires from the user. In this case, the action doesn't require any properties. The `run` function is the function that is called when the action is executed. It takes a single argument, context, which contains the values of the action's properties. The `run` function utilizes the httpClient.sendRequest function to make a GET request, fetching a random ice cream flavor. It incorporates API key authentication in the request headers. Finally, it returns the response body. ## Expose The Definition To make the action readable by Activepieces, add it to the array of actions in the piece definition. ```typescript theme={null} import { createPiece } from '@activepieces/pieces-framework'; // Don't forget to add the following import. import { getIcecreamFlavor } from './lib/actions/get-icecream-flavor'; export const gelato = createPiece({ displayName: 'Gelato', logoUrl: 'https://cdn.activepieces.com/pieces/gelato.png', authors: [], auth: gelatoAuth, // Add the action here. actions: [getIcecreamFlavor], // <-------- triggers: [], }); ``` # Testing By default, the development setup only builds specific components. Open the file `packages/server/api/.env` and include "gelato" in the `AP_DEV_PIECES`. For more details, check out the [Piece Development](./development-setup) section. Once you edit the environment variable, restart the backend. The piece will be rebuilt. After this process, you'll need to **refresh** the frontend to see the changes. If the build fails, try debugging by running `npx nx run-many -t build --projects=gelato`. It will display any errors in your code. To test the action, use the flow builder in Activepieces. It should function as shown in the screenshot. Gelato Action # Create Trigger Source: https://www.activepieces.com/docs/build-pieces/building-pieces/create-trigger This tutorial will guide you through the process of creating trigger for a Gelato piece that fetches new icecream flavor. ## Trigger Definition To create trigger run the following command, ```bash theme={null} npm run cli triggers create ``` 1. `Piece Folder Name`: This is the name associated with the folder where the trigger resides. It helps organize and categorize triggers within the piece. 2. `Trigger Display Name`: The name users see in the interface, conveying the trigger's purpose clearly. 3. `Trigger Description`: A brief, informative text in the UI, guiding users about the trigger's function and purpose. 4. `Trigger Technique`: Specifies the trigger type - either [polling](../piece-reference/triggers/polling-trigger) or [webhook](../piece-reference/triggers/webhook-trigger). **Example:** ```bash theme={null} npm run cli triggers create ? Enter the piece folder name : gelato ? Enter the trigger display name : new flavor created ? Enter the trigger description : triggers when a new icecream flavor is created. ? Select the trigger technique: polling ``` This will create a new TypeScript file at `packages/pieces/community/gelato/src/lib/triggers` named `new-flavor-created.ts`. Inside this file, paste the following code: ```ts theme={null} import { gelatoAuth } from '../../'; import { DedupeStrategy, HttpMethod, HttpRequest, Polling, httpClient, pollingHelper, } from '@activepieces/pieces-common'; import { PiecePropValueSchema, TriggerStrategy, createTrigger, } from '@activepieces/pieces-framework'; import dayjs from 'dayjs'; const polling: Polling< PiecePropValueSchema, Record > = { strategy: DedupeStrategy.TIMEBASED, items: async ({ auth, propsValue, lastFetchEpochMS }) => { const request: HttpRequest = { method: HttpMethod.GET, url: 'https://cloud.activepieces.com/api/v1/webhooks/aHlEaNLc6vcF1nY2XJ2ed/sync', headers: { authorization: auth, }, }; const res = await httpClient.sendRequest(request); return res.body['flavors'].map((flavor: string) => ({ epochMilliSeconds: dayjs().valueOf(), data: flavor, })); }, }; export const newFlavorCreated = createTrigger({ auth: gelatoAuth, name: 'newFlavorCreated', displayName: 'new flavor created', description: 'triggers when a new icecream flavor is created.', props: {}, sampleData: {}, type: TriggerStrategy.POLLING, async test(context) { return await pollingHelper.test(polling, context); }, async onEnable(context) { const { store, auth, propsValue } = context; await pollingHelper.onEnable(polling, { store, auth, propsValue }); }, async onDisable(context) { const { store, auth, propsValue } = context; await pollingHelper.onDisable(polling, { store, auth, propsValue }); }, async run(context) { return await pollingHelper.poll(polling, context); }, }); ``` The way polling triggers usually work is as follows: `Run`:The run method executes every 5 minutes, fetching data from the endpoint within a specified timestamp range or continuing until it identifies the last item ID. It then returns the new items as an array. In this example, the httpClient.sendRequest method is utilized to retrieve new flavors, which are subsequently stored in the store along with a timestamp. ## Expose The Definition To make the trigger readable by Activepieces, add it to the array of triggers in the piece definition. ```typescript theme={null} import { createPiece } from '@activepieces/pieces-framework'; import { getIcecreamFlavor } from './lib/actions/get-icecream-flavor'; // Don't forget to add the following import. import { newFlavorCreated } from './lib/triggers/new-flavor-created'; export const gelato = createPiece({ displayName: 'Gelato Tutorial', logoUrl: 'https://cdn.activepieces.com/pieces/gelato.png', authors: [], auth: gelatoAuth, actions: [getIcecreamFlavor], // Add the trigger here. triggers: [newFlavorCreated], // <-------- }); ``` # Testing By default, the development setup only builds specific components. Open the file `packages/server/api/.env` and include "gelato" in the `AP_DEV_PIECES`. For more details, check out the [Piece Development](./development-setup) section. Once you edit the environment variable, restart the backend. The piece will be rebuilt. After this process, you'll need to **refresh** the frontend to see the changes. To test the trigger, use the load sample data from flow builder in Activepieces. It should function as shown in the screenshot. Gelato Action # Development setup Source: https://www.activepieces.com/docs/build-pieces/building-pieces/development-setup ## Prerequisites * Node.js v18+ * npm v9+ ## Instructions 1. Setup the environment ```bash theme={null} node tools/setup-dev.js ``` 2. Start the environment This command will start activepieces with sqlite3 and in memory queue. ```bash theme={null} npm start ``` By default, the development setup only builds specific pieces.Open the file `packages/server/api/.env` and add comma-separated list of pieces to make available. For more details, check out the [Piece Development](/build-pieces/building-pieces/development-setup#pieces-development) section. 3. Go to ***localhost:4200*** on your web browser and sign in with these details: Email: `dev@ap.com` Password: `12345678` ## Pieces Development When [`AP_SYNC_MODE`](https://github.com/activepieces/activepieces/blob/main/packages/server/api/.env#L17) is set to `OFFICIAL_AUTO`, all pieces are automatically loaded from the cloud API and synced to the database on first launch. This process may take a few seconds to several minutes depending on your internet connection. For local development, pieces are loaded from your local `dist` folder instead of the database. To enable this, set the [`AP_DEV_PIECES`](https://github.com/activepieces/activepieces/blob/main/packages/server/api/.env#L4) environment variable with a comma-separated list of pieces. For example, to develop with `google-sheets` and `cal-com`: ```sh theme={null} AP_DEV_PIECES=google-sheets,cal-com npm start ``` # Overview Source: https://www.activepieces.com/docs/build-pieces/building-pieces/overview This section helps developers build and contribute pieces. Building pieces is fun and important; it allows you to customize Activepieces for your own needs. We love contributions! In fact, most of the pieces are contributed by the community. Feel free to open a pull request. **Friendly Tip:** For the fastest support, we recommend joining our Discord community. We are dedicated to addressing every question and concern raised there. Build pieces using TypeScript for a more powerful and flexible development process. See your changes in the browser within 7 seconds. Work within the open-source environment, explore, and contribute to other pieces. Join our large community, where you can ask questions, share ideas, and develop alongside others. # Add Piece Authentication Source: https://www.activepieces.com/docs/build-pieces/building-pieces/piece-authentication ### Piece Authentication Activepieces supports multiple forms of authentication, you can check those forms [here](../piece-reference/authentication) Now, let's establish authentication for this piece, which necessitates the inclusion of an API Key in the headers. Modify `src/index.ts` file to add authentication, ```ts theme={null} import { PieceAuth, createPiece } from '@activepieces/pieces-framework'; export const gelatoAuth = PieceAuth.SecretText({ displayName: 'API Key', required: true, description: 'Please use **test-key** as value for API Key', }); export const gelato = createPiece({ displayName: 'Gelato', logoUrl: 'https://cdn.activepieces.com/pieces/gelato.png', auth: gelatoAuth, authors: [], actions: [], triggers: [], }); ``` Use the value **test-key** as the API key when testing actions or triggers for Gelato. # Create Piece Definition Source: https://www.activepieces.com/docs/build-pieces/building-pieces/piece-definition This tutorial will guide you through the process of creating a Gelato piece with an action that fetches random icecream flavor and trigger that fetches new icecream flavor created. It assumes that you are familiar with the following: * [Activepieces Local development](./development-setup) Or [GitHub Codespaces](../misc/codespaces). * TypeScript syntax. ## Piece Definition To get started, let's generate a new piece for Gelato ```bash theme={null} npm run cli pieces create ``` You will be asked three questions to define your new piece: 1. `Piece Name`: Specify a name for your piece. This name uniquely identifies your piece within the ActivePieces ecosystem. 2. `Package Name`: Optionally, you can enter a name for the npm package associated with your piece. If left blank, the default name will be used. 3. `Piece Type`: Choose the piece type based on your intention. It can be either "custom" if it's a tailored solution for your needs, or "community" if it's designed to be shared and used by the broader community. **Example:** ```bash theme={null} npm run cli pieces create ? Enter the piece name: gelato ? Enter the package name: @activepieces/piece-gelato ? Select the piece type: community ``` The piece will be generated at `packages/pieces/community/gelato/`, the `src/index.ts` file should contain the following code ```ts theme={null} import { PieceAuth, createPiece } from '@activepieces/pieces-framework'; export const gelato = createPiece({ displayName: 'Gelato', logoUrl: 'https://cdn.activepieces.com/pieces/gelato.png', auth: PieceAuth.None(), authors: [], actions: [], triggers: [], }); ``` # Fork Repository Source: https://www.activepieces.com/docs/build-pieces/building-pieces/setup-fork To start building pieces, we need to fork the repository that contains the framework library and the development environment. Later, we will publish these pieces as `npm` artifacts. Follow these steps to fork the repository: 1. Go to the repository page at [https://github.com/activepieces/activepieces](https://github.com/activepieces/activepieces). 2. Click the `Fork` button located in the top right corner of the page. Fork Repository If you are an enterprise customer and want to use the private pieces feature, you can refer to the tutorial on how to set up a [private fork](../misc/private-fork). # Start Building Source: https://www.activepieces.com/docs/build-pieces/building-pieces/start-building This section guides you in creating a Gelato piece, from setting up your development environment to contributing the piece. By the end of this tutorial, you will have a piece with an action that fetches a random ice cream flavor and a trigger that fetches newly created ice cream flavors. These are the next sections. In each step, we will do one small thing. This tutorial should take around 30 minutes. ## Steps Overview Fork the repository to create your own copy of the codebase. Set up your development environment with the necessary tools and dependencies. Define the structure and behavior of your Gelato piece. Implement authentication mechanisms for your Gelato piece. Create an action that fetches a random ice cream flavor. Create a trigger that fetches newly created ice cream flavors. Share your Gelato piece with others. Contribute a piece to our repo and receive +1,400 tasks/month on [Activepieces Cloud](https://cloud.activepieces.com). # Build Custom Pieces Source: https://www.activepieces.com/docs/build-pieces/misc/build-piece You can use the CLI to build custom pieces for the platform. This process compiles the pieces and exports them as a `.tgz` packed archive. ### How It Works The CLI scans the `packages/pieces/` directory for the specified piece. It checks the **name** in the `package.json` file. If the piece is found, it builds and packages it into a `.tgz` archive. ### Usage To build a piece, follow these steps: 1. Ensure you have the CLI installed by cloning the repository. 2. Run the following command: ```bash theme={null} npm run build-piece ``` You will be prompted to enter the name of the piece you want to build. For example: ```bash theme={null} ? Enter the piece folder name : google-drive ``` The CLI will build the piece and you will be given the path to the archive. For example: ```bash theme={null} Piece 'google-drive' built and packed successfully at dist/packages/pieces/community/google-drive ``` You may also build the piece non-interactively by passing the piece name as an argument. For example: ```bash theme={null} npm run build-piece google-drive ``` # GitHub Codespaces Source: https://www.activepieces.com/docs/build-pieces/misc/codespaces GitHub Codespaces is a cloud development platform that enables developers to write, run, and debug code directly in their browsers, seamlessly integrated with GitHub. ### Steps to setup Codespaces 1. Go to [Activepieces repo](https://github.com/activepieces/activepieces). 2. Click Code `<>`, then under codespaces click create codespace on main. Create Codespace By default, the development setup only builds specific pieces.Open the file `packages/server/api/.env` and add comma-separated list of pieces to make available. For more details, check out the [Piece Development](/build-pieces/building-pieces/development-setup#pieces-development) section. 3. Open the terminal and run `npm start` 4. Access the frontend URL by opening port 4200 and signing in with these details: Email: `dev@ap.com` Password: `12345678` # Dev Containers Source: https://www.activepieces.com/docs/build-pieces/misc/dev-container ## Using Dev Containers in Visual Studio Code The project includes a dev container configuration that allows you to use Visual Studio Code's [Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) extension to develop the project in a consistent environment. This can be especially helpful if you are new to the project or if you have a different environment setup on your local machine. ## Prerequisites Before you can use the dev container, you will need to install the following: * [Visual Studio Code](https://code.visualstudio.com/). * The [Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) extension for Visual Studio Code. * [Docker](https://www.docker.com/). ## Using the Dev Container To use the dev container for the Activepieces project, follow these steps: 1. Clone the Activepieces repository to your local machine. 2. Open the project in Visual Studio Code. 3. Press `Ctrl+Shift+P` and type `> Dev Containers: Reopen in Container`. 4. Run `npm start`. 5. The backend will run at `localhost:3000` and the frontend will run at `localhost:4200`. By default, the development setup only builds specific pieces.Open the file `packages/server/api/.env` and add comma-separated list of pieces to make available. For more details, check out the [Piece Development](/build-pieces/building-pieces/development-setup#pieces-development) section. The login credentials are:\ Email: `dev@ap.com` Password: `12345678` ## Exiting the Dev Container To exit the dev container and return to your local environment, follow these steps: 1. In the bottom left corner of Visual Studio Code, click the `Remote-Containers: Reopen folder locally` button. 2. Visual Studio Code will close the connection to the dev container and reopen the project in your local environment. ## Troubleshoot One of the best trouble shoot after an error occur is to reset the dev container. 1. Exit the dev container 2. Run the following ```sh theme={null} sh tools/reset-dev.sh ``` 3. Rebuild the dev container from above steps # Custom Pieces CI/CD Source: https://www.activepieces.com/docs/build-pieces/misc/pieces-ci-cd You can use the CLI to sync custom pieces. There is no need to rebuild the Docker image as they are loaded directly from npm. ### How It Works Use the CLI to sync items from `packages/pieces/custom/` to instances. In production, Activepieces acts as an npm registry, storing all piece versions. The CLI scans the directory for `package.json` files, checking the **name** and **version** of each piece. If a piece isn't uploaded, it packages and uploads it via the API. ### Usage To use the CLI, follow these steps: 1. Generate an API Key from the Admin Interface. Go to Settings and generate the API Key. 2. Install the CLI by cloning the repository. 3. Run the following command, replacing `API_KEY` with your generated API Key and `INSTANCE_URL` with your instance URL: ```bash theme={null} AP_API_KEY=your_api_key_here bun run sync-pieces -- --apiUrl https://INSTANCE_URL/api ``` ### Developer Workflow 1. Developers create and modify the pieces offline. 2. Increment the piece version in their corresponding `package.json`. For more information, refer to the [piece versioning](../piece-reference/piece-versioning) documentation. 3. Open a pull request towards the main branch. 4. Once the pull request is merged to the main branch, manually run the CLI or use a GitHub/GitLab Action to trigger the synchronization process. ### GitHub Action ```yaml theme={null} name: Sync Custom Pieces on: push: branches: - main workflow_dispatch: jobs: sync-pieces: runs-on: ubuntu-latest steps: # Step 1: Check out the repository code with full history - name: Check out repository code uses: actions/checkout@v3 with: fetch-depth: 0 # Step 2: Set up Bun - name: Set up Bun uses: oven-sh/setup-bun@v1 with: bun-version: latest # Step 3: Cache Bun dependencies - name: Cache Bun dependencies uses: actions/cache@v3 with: path: ~/.bun/install/cache key: bun-${{ hashFiles('bun.lockb') }} restore-keys: | bun- # Step 4: Install dependencies using Bun - name: Install dependencies run: bun install --no-save # Step 5: Sync Custom Pieces - name: Sync Custom Pieces env: AP_API_KEY: ${{ secrets.AP_API_KEY }} run: bun run sync-pieces -- --apiUrl ${{ secrets.INSTANCE_URL }}/api ``` # Setup Private Fork Source: https://www.activepieces.com/docs/build-pieces/misc/private-fork **Friendly Tip #1:** If you want to experiment, you can fork or clone the public repository. For private piece installation, you will need the paid edition. However, you can still develop pieces, contribute them back, **OR** publish them to the public npm registry and use them in your own instance or project. ## Create a Private Fork (Private Pieces) By following these steps, you can create a private fork on GitHub, GitLab or another platform and configure the "activepieces" repository as the upstream source, allowing you to incorporate changes from the "activepieces" repository. 1. **Clone the Repository:** Begin by creating a bare clone of the repository. Remember that this is a temporary step and will be deleted later. ```bash theme={null} git clone --bare git@github.com:activepieces/activepieces.git ``` 2. **Create a Private Git Repository** Generate a new private repository on GitHub or your chosen platform. When initializing the new repository, do not include a README, license, or gitignore files. This precaution is essential to avoid merge conflicts when synchronizing your fork with the original repository. 3. **Mirror-Push to the Private Repository:** Mirror-push the bare clone you created earlier to your newly created "activepieces" repository. Make sure to replace `` in the URL below with your actual GitHub username. ```bash theme={null} cd activepieces.git git push --mirror git@github.com:/activepieces.git ``` 4. **Remove the Temporary Local Repository:** ```bash theme={null} cd .. rm -rf activepieces.git ``` 5. **Clone Your Private Repository:** Now, you can clone your "activepieces" repository onto your local machine into your desired directory. ```bash theme={null} cd ~/path/to/directory git clone git@github.com:/activepieces.git ``` 6. **Add the Original Repository as a Remote:** If desired, you can add the original repository as a remote to fetch potential future changes. However, remember to disable push operations for this remote, as you are not permitted to push changes to it. ```bash theme={null} git remote add upstream git@github.com:activepieces/activepieces.git git remote set-url --push upstream DISABLE ``` You can view a list of all your remotes using `git remote -v`. It should resemble the following: ``` origin git@github.com:/activepieces.git (fetch) origin git@github.com:/activepieces.git (push) upstream git@github.com:activepieces/activepieces.git (fetch) upstream DISABLE (push) ``` > When pushing changes, always use `git push origin`. ### Sync Your Fork To retrieve changes from the "upstream" repository, fetch the remote and rebase your work on top of it. ```bash theme={null} git fetch upstream git merge upstream/main ``` Conflict resolution should not be necessary since you've only added pieces to your repository. # Publish Custom Pieces Source: https://www.activepieces.com/docs/build-pieces/misc/publish-piece You can use the CLI to publish custom pieces to the platform. This process packages the pieces and uploads them to the specified API endpoint. ### How It Works The CLI scans the `packages/pieces/` directory for the specified piece. It checks the **name** and **version** in the `package.json` file. If the piece is not already published, it builds, packages, and uploads it to the platform using the API. ### Usage To publish a piece, follow these steps: 1. Ensure you have an API Key. Generate it from the Admin Interface by navigating to Settings. 2. Install the CLI by cloning the repository. 3. Run the following command: ```bash theme={null} npm run publish-piece-to-api ``` 4. You will be asked three questions to publish your piece: * `Piece Folder Name`: This is the name associated with the folder where the action resides. It helps organize and categorize actions within the piece. * `API URL`: This is the URL of the API endpoint where the piece will be published (ex: [https://cloud.activepieces.com/api](https://cloud.activepieces.com/api)). * `API Key Source`: This is the source of the API key. It can be either `Env Variable (AP_API_KEY)` or `Manually`. In case you choose `Env Variable (AP_API_KEY)`, the CLI will use the API key from the `.env` file in the `packages/server/api` directory. In case you choose `Manually`, you will be asked to enter the API key. Examples: ```bash theme={null} npm run publish-piece-to-api ? Enter the piece folder name : google-drive ? Enter the API URL : https://cloud.activepieces.com/api ? Enter the API Key Source : Env Variable (AP_API_KEY) ``` ```bash theme={null} npm run publish-piece-to-api ? Enter the piece folder name : google-drive ? Enter the API URL : https://cloud.activepieces.com/api ? Enter the API Key Source : Manually ? Enter the API Key : ap_1234567890abcdef1234567890abcdef ``` # Piece Auth Source: https://www.activepieces.com/docs/build-pieces/piece-reference/authentication Learn about piece authentication Piece authentication is used to gather user credentials and securely store them for future use in different flows. The authentication must be defined as the `auth` parameter in the `createPiece`, `createTrigger`, and `createAction` functions. This requirement ensures that the type of authentication can be inferred correctly in triggers and actions. The auth parameter for `createPiece`, `createTrigger`, and `createAction` functions can take an array, but you cannot have more than one auth property of the same type, i.e two OAUTH2 properties. ### Secret Text This authentication collects sensitive information, such as passwords or API keys. It is displayed as a masked input field. **Example:** ```typescript theme={null} PieceAuth.SecretText({ displayName: 'API Key', description: 'Enter your API key', required: true, // Optional Validation validate: async ({auth}) => { if(auth.startsWith('sk_')){ return { valid: true, } } return { valid: false, error: 'Invalid Api Key' } } }) ``` ### Username and Password This authentication collects a username and password as separate fields. **Example:** ```typescript theme={null} PieceAuth.BasicAuth({ displayName: 'Credentials', description: 'Enter your username and password', required: true, username: { displayName: 'Username', description: 'Enter your username', }, password: { displayName: 'Password', description: 'Enter your password', }, // Optional Validation validate: async ({auth}) => { if(auth){ return { valid: true, } } return { valid: false, error: 'Invalid Api Key' } } }) ``` ### Custom This authentication allows for custom authentication by collecting specific properties, such as a base URL and access token. **Example:** ```typescript theme={null} PieceAuth.CustomAuth({ displayName: 'Custom Authentication', description: 'Enter custom authentication details', props: { base_url: Property.ShortText({ displayName: 'Base URL', description: 'Enter the base URL', required: true, }), access_token: PieceAuth.SecretText({ displayName: 'Access Token', description: 'Enter the access token', required: true }) }, // Optional Validation validate: async ({auth}) => { if(auth){ return { valid: true, } } return { valid: false, error: 'Invalid Api Key' } }, required: true }) ``` ### OAuth2 This authentication collects OAuth2 authentication details, including the authentication URL, token URL, and scope. **Example:** ```typescript theme={null} PieceAuth.OAuth2({ displayName: 'OAuth2 Authentication', grantType: OAuth2GrantType.AUTHORIZATION_CODE, required: true, authUrl: 'https://example.com/auth', tokenUrl: 'https://example.com/token', scope: ['read', 'write'] }) ``` Please note `OAuth2GrantType.CLIENT_CREDENTIALS` is also supported for service-based authentication. # Enable Custom API Calls Source: https://www.activepieces.com/docs/build-pieces/piece-reference/custom-api-calls Learn how to enable custom API calls for your pieces Custom API Calls allow the user to send a request to a specific endpoint if no action has been implemented for it. This will show in the actions list of the piece as `Custom API Call`, to enable this action for a piece, you need to call the `createCustomApiCallAction` in your actions array. ## Basic Example The example below implements the action for the OpenAI piece. The OpenAI piece uses a `Bearer token` authorization header to identify the user sending the request. ```typescript theme={null} actions: [ ...yourActions, createCustomApiCallAction({ // The auth object defined in the piece auth: openaiAuth, // The base URL for the API baseUrl: () => { 'https://api.openai.com/v1' }, // Mapping the auth object to the needed authorization headers authMapping: async (auth) => { return { 'Authorization': `Bearer ${auth}` } } }) ] ``` ## Dynamic Base URL and Basic Auth Example The example below implements the action for the Jira Cloud piece. The Jira Cloud piece uses a dynamic base URL for it's actions, where the base URL changes based on the values the user authenticated with. We will also implement a Basic authentication header. ```typescript theme={null} actions: [ ...yourActions, createCustomApiCallAction({ baseUrl: (auth) => { return `${(auth as JiraAuth).instanceUrl}/rest/api/3` }, auth: jiraCloudAuth, authMapping: async (auth) => { const typedAuth = auth as JiraAuth return { 'Authorization': `Basic ${typedAuth.email}:${typedAuth.apiToken}` } } }) ] ``` # Piece Examples Source: https://www.activepieces.com/docs/build-pieces/piece-reference/examples Explore a collection of example triggers and actions To get the full benefit, it is recommended to read the tutorial first. ## Triggers: **Webhooks:** * [New Form Submission on Typeform](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/typeform/src/lib/trigger/new-submission.ts) **Polling:** * [New Completed Task On Todoist](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/todoist/src/lib/triggers/task-completed-trigger.ts) ## Actions: * [Send a message On Discord](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/discord/src/lib/actions/send-message-webhook.ts) * [Send an mail On Gmail](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/gmail/src/lib/actions/send-email-action.ts) ## Authentication **OAuth2:** * [Slack](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/slack/src/index.ts) * [Gmail](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/gmail/src/index.ts) **API Key:** * [Sendgrid](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/sendgrid/src/index.ts) **Basic Authentication:** * [Twilio](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/twilio/src/index.ts) # External Libraries Source: https://www.activepieces.com/docs/build-pieces/piece-reference/external-libraries Learn how to install and use external libraries. The Activepieces repository is structured as a monorepo, employing Nx as its build tool. To keep our main `package.json` as light as possible, we keep libraries that are only used for a piece in the piece `package.json` . This means when adding a new library you should navigate to the piece folder and install the library with our package manager `bun` ```bash theme={null} cd packages/pieces/ bun install --save ``` * Import the library into your piece. Guidelines: * Make sure you are using well-maintained libraries. * Ensure that the library size is not too large to avoid bloating the bundle size; this will make the piece load faster in the sandbox. # Files Source: https://www.activepieces.com/docs/build-pieces/piece-reference/files Learn how to use files object to create file references. The `ctx.files` object allow you to store files in local storage or in a remote storage depending on the run environment. ## Write You can use the `write` method to write a file to the storage, It returns a string that can be used in other actions or triggers properties to reference the file. **Example:** ```ts theme={null} const fileReference = await files.write({ fileName: 'file.txt', data: Buffer.from('text') }); ``` This code will store the file in the database If the run environment is testing mode since it will be required to test other steps, other wise it will store it in the local temporary directory. For Reading the file If you are using the file property in a trigger or action, It will be automatically parsed and you can use it directly, please refer to `Property.File` in the [properties](./properties#file) section. # Flow Control Source: https://www.activepieces.com/docs/build-pieces/piece-reference/flow-control Learn How to Control Flow from Inside the Piece Flow Controls provide the ability to control the flow of execution from inside a piece. By using the `ctx` parameter in the `run` method of actions, you can perform various operations to control the flow. ## Stop Flow You can stop the flow and provide a response to the webhook trigger. This can be useful when you want to terminate the execution of the piece and send a specific response back. **Example with Response:** ```typescript theme={null} context.run.stop({ response: { status: context.propsValue.status ?? StatusCodes.OK, body: context.propsValue.body, headers: (context.propsValue.headers as Record) ?? {}, }, }); ``` **Example without Response:** ```typescript theme={null} context.run.stop(); ``` ## Pause Flow and Wait for Webhook You can pause flow and return HTTP response, also provide a callback to URL that you can call with certain payload and continue the flow. **Example:** ```typescript theme={null} ctx.run.pause({ pauseMetadata: { type: PauseType.WEBHOOK, response: { callbackUrl: context.generateResumeUrl({ queryParams: {}, }), }, }, }); ``` ## Pause Flow and Delay You can pause or delay the flow until a specific timestamp. Currently, the only supported type of pause is a delay based on a future timestamp. **Example:** ```typescript theme={null} ctx.run.pause({ pauseMetadata: { type: PauseType.DELAY, resumeDateTime: futureTime.toUTCString() } }); ``` These flow hooks give you control over the execution of the piece by allowing you to stop the flow or pause it until a certain condition is met. You can use these hooks to customize the behavior and flow of your actions. # Piece i18n Source: https://www.activepieces.com/docs/build-pieces/piece-reference/i18n Learn about translating pieces to multiple locales Run the following command to create a translation file with all the strings that need translation in your piece ```bash theme={null} npm run cli pieces generate-translation-file PIECE_FOLDER_NAME ``` Make a copy of `packages/pieces///src/i18n/translation.json`, name it `.json` i.e fr.json and translate the values. For open source pieces, you can use the [Crowdin project](https://crowdin.com/project/activepieces) to translate to different languages. These translations will automatically sync back to your code. After following the steps to [setup your development environment](/build-pieces/building-pieces/development-setup), click the small cog icon next to the logo in your dashboard and change the locale. Locales
In the builder your piece will now appear in the translated language: French Webhooks
Follow the docs here to [publish your piece](/build-pieces/sharing-pieces/overview)
# Persistent Storage Source: https://www.activepieces.com/docs/build-pieces/piece-reference/persistent-storage Learn how to store and retrieve data from a key-value store The `ctx` parameter inside triggers and actions provides a simple key/value storage mechanism. The storage is persistent, meaning that the stored values are retained even after the execution of the piece. By default, the storage operates at the flow level, but it can also be configured to store values at the project level. The storage scope is completely isolated. If a key is stored in a different scope, it will not be fetched when requested in different scope. ## Put You can store a value with a specified key in the storage. **Example:** ```typescript theme={null} ctx.store.put('KEY', 'VALUE', StoreScope.PROJECT); ``` ## Get You can retrieve the value associated with a specific key from the storage. **Example:** ```typescript theme={null} const value = ctx.store.get('KEY', StoreScope.PROJECT); ``` ## Delete You can delete a key-value pair from the storage. **Example:** ```typescript theme={null} ctx.store.delete('KEY', StoreScope.PROJECT); ``` These storage operations allow you to store, retrieve, and delete key-value pairs in the persistent storage. You can use this storage mechanism to store and retrieve data as needed within your triggers and actions. # Piece Versioning Source: https://www.activepieces.com/docs/build-pieces/piece-reference/piece-versioning Learn how to version your pieces Pieces are npm packages and follows **semantic versioning**. ## Semantic Versioning The version number consists of three numbers: `MAJOR.MINOR.PATCH`, where: * **MAJOR** It should be incremented when there are breaking changes to the piece. * **MINOR** It should be incremented for new features or functionality that is compatible with the previous version, unless the major version is less than 1.0, in which case it can be a breaking change. * **PATCH** It should be incremented for bug fixes and small changes that do not introduce new features or break backward compatibility. ## Engine The engine will use the most up-to-date compatible version for a given piece version during the **DRAFT** flow versions. Once the flow is published, all pieces will be locked to a specific version. **Case 1: Piece Version is Less Than 1.0**: The engine will select the latest **patch** version that shares the same **minor** version number. **Case 2: Piece Version Reaches Version 1.0**: The engine will select the latest **minor** version that shares the same **major** version number. ## Examples when you make a change, remember to increment the version accordingly. ### Breaking changes * Remove an existing action. * Add a required `action` prop. * Remove an existing action prop, whether required or optional. * Remove an attribute from an action output. * Change the existing behavior of an action/trigger. ### Non-breaking changes * Add a new action. * Add an optional `action` prop. * Add an attribute to an action output. i.e., any removal is breaking, any required addition is breaking, everything else is not breaking. # Props Source: https://www.activepieces.com/docs/build-pieces/piece-reference/properties Learn about different types of properties used in triggers / actions Properties are used in actions and triggers to collect information from the user. They are also displayed to the user for input. Here are some commonly used properties: ## Basic Properties These properties collect basic information from the user. ### Short Text This property collects a short text input from the user. **Example:** ```typescript theme={null} Property.ShortText({ displayName: 'Name', description: 'Enter your name', required: true, defaultValue: 'John Doe', }); ``` ### Long Text This property collects a long text input from the user. **Example:** ```typescript theme={null} Property.LongText({ displayName: 'Description', description: 'Enter a description', required: false, }); ``` ### Checkbox This property presents a checkbox for the user to select or deselect. **Example:** ```typescript theme={null} Property.Checkbox({ displayName: 'Agree to Terms', description: 'Check this box to agree to the terms', required: true, defaultValue: false, }); ``` ### Markdown This property displays a markdown snippet to the user, useful for documentation or instructions. It includes a `variant` option to style the markdown, using the `MarkdownVariant` enum: * **BORDERLESS**: For a minimalistic, no-border layout. * **INFO**: Displays informational messages. * **WARNING**: Alerts the user to cautionary information. * **TIP**: Highlights helpful tips or suggestions. The default value for `variant` is **INFO**. **Example:** ```typescript theme={null} Property.MarkDown({ value: '## This is a markdown snippet', variant: MarkdownVariant.WARNING, }), ``` If you want to show a webhook url to the user, use `{{ webhookUrl }}` in the markdown snippet. ### DateTime This property collects a date and time from the user. **Example:** ```typescript theme={null} Property.DateTime({ displayName: 'Date and Time', description: 'Select a date and time', required: true, defaultValue: '2023-06-09T12:00:00Z', }); ``` ### Number This property collects a numeric input from the user. **Example:** ```typescript theme={null} Property.Number({ displayName: 'Quantity', description: 'Enter a number', required: true, }); ``` ### Static Dropdown This property presents a dropdown menu with predefined options. **Example:** ```typescript theme={null} Property.StaticDropdown({ displayName: 'Country', description: 'Select your country', required: true, options: { options: [ { label: 'Option One', value: '1', }, { label: 'Option Two', value: '2', }, ], }, }); ``` ### Static Multiple Dropdown This property presents a dropdown menu with multiple selection options. **Example:** ```typescript theme={null} Property.StaticMultiSelectDropdown({ displayName: 'Colors', description: 'Select one or more colors', required: true, options: { options: [ { label: 'Red', value: 'red', }, { label: 'Green', value: 'green', }, { label: 'Blue', value: 'blue', }, ], }, }); ``` ### JSON This property collects JSON data from the user. **Example:** ```typescript theme={null} Property.Json({ displayName: 'Data', description: 'Enter JSON data', required: true, defaultValue: { key: 'value' }, }); ``` ### Dictionary This property collects key-value pairs from the user. **Example:** ```typescript theme={null} Property.Object({ displayName: 'Options', description: 'Enter key-value pairs', required: true, defaultValue: { key1: 'value1', key2: 'value2', }, }); ``` ### File This property collects a file from the user, either by providing a URL or uploading a file. **Example:** ```typescript theme={null} Property.File({ displayName: 'File', description: 'Upload a file', required: true, }); ``` ### Array of Strings This property collects an array of strings from the user. **Example:** ```typescript theme={null} Property.Array({ displayName: 'Tags', description: 'Enter tags', required: false, defaultValue: ['tag1', 'tag2'], }); ``` ### Array of Fields This property collects an array of objects from the user. **Example:** ```typescript theme={null} Property.Array({ displayName: 'Fields', description: 'Enter fields', properties: { fieldName: Property.ShortText({ displayName: 'Field Name', required: true, }), fieldType: Property.StaticDropdown({ displayName: 'Field Type', required: true, options: { options: [ { label: 'TEXT', value: 'TEXT' }, { label: 'NUMBER', value: 'NUMBER' }, ], }, }), }, required: false, defaultValue: [], }); ``` ## Dynamic Data Properties These properties provide more advanced options for collecting user input. ### Dropdown This property allows for dynamically loaded options based on the user's input. **Example:** ```typescript theme={null} Property.Dropdown({ displayName: 'Options', description: 'Select an option', required: true, auth: yourPieceAuth, refreshers: ['auth'], refreshOnSearch: false, options: async ({ auth }, { searchValue }) => { // Search value only works when refreshOnSearch is true if (!auth) { return { disabled: true, }; } return { options: [ { label: 'Option One', value: '1', }, { label: 'Option Two', value: '2', }, ], }; }, }); ``` When accessing the Piece auth, be sure to use exactly `auth` as it is hardcoded. However, for other properties, use their respective names. ### Multi-Select Dropdown This property allows for multiple selections from dynamically loaded options. **Example:** ```typescript theme={null} Property.MultiSelectDropdown({ displayName: 'Options', description: 'Select one or more options', required: true, refreshers: ['auth'], auth: yourPieceAuth, options: async ({ auth }) => { if (!auth) { return { disabled: true, }; } return { options: [ { label: 'Option One', value: '1', }, { label: 'Option Two', value: '2', }, ], }; }, }); ``` When accessing the Piece auth, be sure to use exactly `auth` as it is hardcoded. However, for other properties, use their respective names. ### Dynamic Properties This property is used to construct forms dynamically based on API responses or user input. **Example:** ```typescript theme={null} import { httpClient, HttpMethod, } from '@activepieces/pieces-common'; Property.DynamicProperties({ description: 'Dynamic Form', displayName: 'Dynamic Form', required: true, refreshers: ['auth'], auth: yourPieceAuth, props: async ({auth}) => { const apiEndpoint = 'https://someapi.com'; const response = await httpClient.sendRequest<{ values: [string[]][] }>({ method: HttpMethod.GET, url: apiEndpoint , //you can add the auth value to the headers }); const properties = { prop1: Property.ShortText({ displayName: 'Property 1', description: 'Enter property 1', required: true, }), prop2: Property.Number({ displayName: 'Property 2', description: 'Enter property 2', required: false, }), }; return properties; }, }); ``` ### Custom Property (BETA) This feature is still in BETA and not fully released yet, please let us know if you use it and face any issues and consider it a possibility could have breaking changes in the future This is a property that lets you inject JS code into the frontend and manipulate the DOM of this content however you like, it is extremely useful in case you are [embedding](/embedding/overview) Activepieces and want to have a way to communicate with the SaaS embedding it. It has a `code` property which is a function that takes in an object parameter which will have the following schema: | Parameter Name | Type | Description | | -------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | onChange | `(value:unknown)=>void` | A callback you call to set the value of your input (only call this inside event handlers) | | value | `unknown` | Whatever the type of the value you pass to onChange | | containerId | `string` | The ID of an HTML element in which you can modify the DOM however you like | | isEmbedded | `boolean` | The flag that tells you if the code is running inside an [embedded instance](/embedding/overview) of Activepieces | | projectId | `string` | The project ID of the flow the step that contains this property is in | | disabled | `boolean` | The flag that tells you whether or not the property is disabled | | property | `{ displayName:string, description?: string, required: boolean}` | The current property information | * You can return a clean up function at the end of the `code` property function to remove any listeners or HTML elements you inserted (this is important for development mode, the component gets [mounted twice](https://react.dev/reference/react/useEffect#my-effect-runs-twice-when-the-component-mounts)). * This function must be pure without any imports from external packages or variables outside the function scope. * **Must** mark your piece `minimumSupportedRelease` property to be at least `0.58.0` after introducing this property to it. Here is how to define such a property: ```typescript theme={null} Property.Custom({ code:(({value,onChange,containerId})=>{ const container = document.getElementById(containerId); const input = document.createElement('input'); input.classList.add(...['border','border-solid', 'border-border', 'rounded-md']) input.type = 'text'; input.value = `${value}`; input.oninput = (e: Event) => { const value = (e.target as HTMLInputElement).value; onChange(value); } container!.appendChild(input); const windowCallback = (e:MessageEvent<{type:string,value:string,propertyName:string}>) => { if(e.data.type === 'updateInput' && e.data.propertyName === 'YOUR_PROPERTY_NAME'){ input.value= e.data.value; onChange(e.data.value); } } window.addEventListener('message', windowCallback); return ()=>{ window.removeEventListener('message', windowCallback); container!.removeChild(input); } }), displayName: 'Custom Property', required: true }) ``` * If you would like to know more about how to setup communication between Activepieces and the SaaS that's embedding it, check the [window postMessage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage). # Props Validation Source: https://www.activepieces.com/docs/build-pieces/piece-reference/properties-validation Learn about different types of properties validation Activepieces uses Zod for runtime validation of piece properties. Zod provides a powerful schema validation system that helps ensure your piece receives valid inputs. To use Zod validation in your piece, first import the validation helper and Zod: Please make sure the `minimumSupportedRelease` is set to at least `0.36.1` for the validation to work. ```typescript theme={null} import { createAction, Property } from '@activepieces/pieces-framework'; import { propsValidation } from '@activepieces/pieces-common'; import { z } from 'zod'; export const getIcecreamFlavor = createAction({ name: 'get_icecream_flavor', // Unique name for the action. displayName: 'Get Ice Cream Flavor', description: 'Fetches a random ice cream flavor based on user preferences.', props: { sweetnessLevel: Property.Number({ displayName: 'Sweetness Level', required: true, description: 'Specify the sweetness level (0 to 10).', }), includeToppings: Property.Checkbox({ displayName: 'Include Toppings', required: false, description: 'Should the flavor include toppings?', defaultValue: true, }), numberOfFlavors: Property.Number({ displayName: 'Number of Flavors', required: true, description: 'How many flavors do you want to fetch? (1-5)', defaultValue: 1, }), }, async run({ propsValue }) { // Validate the input properties using Zod await propsValidation.validateZod(propsValue, { sweetnessLevel: z.number().min(0).max(10, 'Sweetness level must be between 0 and 10.'), numberOfFlavors: z.number().min(1).max(5, 'You can fetch between 1 and 5 flavors.'), }); // Action logic const sweetnessLevel = propsValue.sweetnessLevel; const includeToppings = propsValue.includeToppings ?? true; // Default to true const numberOfFlavors = propsValue.numberOfFlavors; // Simulate fetching random ice cream flavors const allFlavors = [ 'Vanilla', 'Chocolate', 'Strawberry', 'Mint', 'Cookie Dough', 'Pistachio', 'Mango', 'Coffee', 'Salted Caramel', 'Blackberry', ]; const selectedFlavors = allFlavors.slice(0, numberOfFlavors); return { message: `Here are your ${numberOfFlavors} flavors: ${selectedFlavors.join(', ')}`, sweetnessLevel: sweetnessLevel, includeToppings: includeToppings, }; }, }); ``` # Overview Source: https://www.activepieces.com/docs/build-pieces/piece-reference/triggers/overview This tutorial explains three techniques for creating triggers: * `Polling`: Periodically call endpoints to check for changes. * `Webhooks`: Listen to user events through a single URL. * `App Webhooks (Subscriptions)`: Use a developer app (using OAuth2) to receive all authorized user events at a single URL (Not Supported). to create new trigger run following command, ```bash theme={null} npm run cli triggers create ``` 1. `Piece Folder Name`: This is the name associated with the folder where the trigger resides. It helps organize and categorize triggers within the piece. 2. `Trigger Display Name`: The name users see in the interface, conveying the trigger's purpose clearly. 3. `Trigger Description`: A brief, informative text in the UI, guiding users about the trigger's function and purpose. 4. `Trigger Technique`: Specifies the trigger type - either polling or webhook. # Trigger Structure ```typescript theme={null} export const createNewIssue = createTrigger({ auth: PieceAuth | undefined name: string, // Unique name across the piece. displayName: string, // Display name on the interface. description: string, // Description for the action sampleData: null, type: TriggerStrategy.WEBHOOK | TriggerStrategy.POLLING | TriggerStrategy.APP_WEBHOOK, props: {}; // Required properties from the user. // Run when the user enable or publish the flow. onEnable: (ctx) => {}, // Run when the user disable the flow or // the old flow is deleted after new one is published. onDisable: (ctx) => {}, // Trigger implementation, It takes context as parameter. // should returns an array of payload, each payload considered run: async run(ctx): unknown[] => {} }) ``` It's important to note that the `run` method returns an array. The reason for this is that a single polling can contain multiple triggers, so each item in the array will trigger the flow to run. ## Context Object The Context object contains multiple helpful pieces of information and tools that can be useful while developing. ```typescript theme={null} // Store: A simple, lightweight key-value store that is helpful when you are developing triggers that persist between runs, used to store information like the last polling date. await context.store.put('_lastFetchedDate', new Date()); const lastFetchedData = await context.store.get('_lastFetchedDate', new Date()); // Webhook URL: A unique, auto-generated URL that will trigger the flow. Useful when you need to develop a trigger based on webhooks. context.webhookUrl; // Payload: Contains information about the HTTP request sent by the third party. It has three properties: status, headers, and body. context.payload; // PropsValue: Contains the information filled by the user in defined properties. context.propsValue; ``` **App Webhooks (Not Supported)** Certain services, such as `Slack` and `Square`, only support webhooks at the developer app level. This means that all authorized users for the app will be sent to the same endpoint. While this technique will be supported soon, for now, a workaround is to perform polling on the endpoint. # Polling Trigger Source: https://www.activepieces.com/docs/build-pieces/piece-reference/triggers/polling-trigger Periodically call endpoints to check for changes The way polling triggers usually work is as follows: **On Enable:** Store the last timestamp or most recent item id using the context store property. **Run:** This method runs every **5 minutes**, fetches the endpoint between a certain timestamp or traverses until it finds the last item id, and returns the new items as an array. **Testing:** You can implement a test function which should return some of the most recent items. It's recommended to limit this to five. **Examples:** * [New Record Airtable](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/airtable/src/lib/trigger/new-record.trigger.ts) * [New Updated Item Salesforce](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/salesforce/src/lib/trigger/new-updated-record.ts) # Polling library There multiple strategy to implement polling triggers, and we have created a library to help you with that. ## Strategies **Timebased:** This strategy fetches new items using a timestamp. You need to implement the items method, which should return the most recent items. The library will detect new items based on the timestamp. The polling object's generic type consists of the props value and the object type. ```typescript theme={null} const polling: Polling> = { strategy: DedupeStrategy.TIMEBASED, items: async ({ propsValue, lastFetchEpochMS }) => { // Todo implement the logic to fetch the items const items = [ {id: 1, created_date: '2021-01-01T00:00:00Z'}, {id: 2, created_date: '2021-01-01T00:00:00Z'}]; return items.map((item) => ({ epochMilliSeconds: dayjs(item.created_date).valueOf(), data: item, })); } } ``` **Last ID Strategy:** This strategy fetches new items based on the last item ID. To use this strategy, you need to implement the items method, which should return the most recent items. The library will detect new items after the last item ID. The polling object's generic type consists of the props value and the object type ```typescript theme={null} const polling: Polling, Record> = { strategy: DedupeStrategy.LAST_ITEM, items: async ({ propsValue }) => { // Implement the logic to fetch the items const items = [{ id: 1 }, { id: 2 }]; return items.map((item) => ({ id: item.id, data: item, })); } } ``` ## Trigger Implementation After implementing the polling object, you can use the polling helper to implement the trigger. ```typescript theme={null} export const newTicketInView = createTrigger({ name: 'new_ticket_in_view', displayName: 'New ticket in view', description: 'Triggers when a new ticket is created in a view', type: TriggerStrategy.POLLING, props: { authentication: Property.SecretText({ displayName: 'Authentication', description: markdownProperty, required: true, }), }, sampleData: {}, onEnable: async (context) => { await pollingHelper.onEnable(polling, { store: context.store, propsValue: context.propsValue, auth: context.auth }) }, onDisable: async (context) => { await pollingHelper.onDisable(polling, { store: context.store, propsValue: context.propsValue, auth: context.auth }) }, run: async (context) => { return await pollingHelper.poll(polling, context); }, test: async (context) => { return await pollingHelper.test(polling, context); } }); ``` # Webhook Trigger Source: https://www.activepieces.com/docs/build-pieces/piece-reference/triggers/webhook-trigger Listen to user events through a single URL The way webhook triggers usually work is as follows: **On Enable:** Use `context.webhookUrl` to perform an HTTP request to register the webhook in a third-party app, and store the webhook Id in the `store`. **On Handshake:** Some services require a successful handshake request usually consisting of some challenge. It works similar to a normal run except that you return the correct challenge response. This is optional and in order to enable the handshake you need to configure one of the available handshake strategies in the `handshakeConfiguration` option. **Run:** You can find the HTTP body inside `context.payload.body`. If needed, alter the body; otherwise, return an array with a single item `context.payload.body`. **Disable:** Using the `context.store`, fetch the webhook ID from the enable step and delete the webhook on the third-party app. **Testing:** You cannot test it with Test Flow, as it uses static sample data provided in the piece. To test the trigger, publish the flow, perform the event. Then check the flow runs from the main dashboard. **Examples:** * [New Form Submission on Typeform](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/typeform/src/lib/trigger/new-submission.ts) To make your webhook accessible from the internet, you need to configure the backend URL. Follow these steps: 1. Install ngrok. 2. Run the command `ngrok http 4200`. 3. Replace the `AP_FRONTEND_URL` environment variable in `packages/server/api/.env` with the ngrok URL. 4. Go to /packages/react-ui/vite.config.ts, uncomment allowedHosts and set the value to what ngrok gives you. Once you have completed these configurations, you are good to go! # Community (Public NPM) Source: https://www.activepieces.com/docs/build-pieces/sharing-pieces/community Learn how to publish your piece to the community. You can publish your pieces to the npm registry and share them with the community. Users can install your piece from Settings -> My Pieces -> Install Piece -> type in the name of your piece package. Make sure you are logged in to npm. If not, please run: ```bash theme={null} npm login ``` Rename the piece name in `package.json` to something unique or related to your organization's scope (e.g., `@my-org/piece-PIECE_NAME`). You can find it at `packages/pieces/PIECE_NAME/package.json`. Don't forget to increase the version number in `package.json` for each new release. Replace `PIECE_FOLDER_NAME` with the name of the folder. Run the following command: ```bash theme={null} npm run publish-piece PIECE_FOLDER_NAME ``` **Congratulations! You can now import the piece from the settings page.** # Contribute Source: https://www.activepieces.com/docs/build-pieces/sharing-pieces/contribute Learn how to contribute a piece to the main repository. * Build and test your piece. * Open a pull request from your repository to the main fork. * A maintainer will review your work closely. * Once the pull request is approved, it will be merged into the main branch. * Your piece will be available within a few minutes. * An automatic GitHub action will package it and create an npm package on npmjs.com. # Overview Source: https://www.activepieces.com/docs/build-pieces/sharing-pieces/overview Learn the different ways to publish your own piece on activepieces. ## Methods * [Contribute Back](/build-pieces/sharing-pieces/contribute): Publish your piece by contributing back your piece to main repository. * [Community](/build-pieces/sharing-pieces/community): Publish your piece on npm directly and share it with the community. * [Private](/build-pieces/sharing-pieces/private): Publish your piece on activepieces privately. # Private Source: https://www.activepieces.com/docs/build-pieces/sharing-pieces/private Learn how to share your pieces privately. This guide assumes you have already created a piece and created a private fork of our repository, and you would like to package it as a file and upload it. Friendly Tip: There is a CLI to easily upload it to your platform. Please check out [Publish Custom Pieces](../misc/publish-piece). Build the piece using the following command. Make sure to replace `${name}` with your piece name. ```bash theme={null} npm run pieces -- build --name=${name} ``` More information about building pieces can be found [here](../misc/build-piece). Upload the generated tarball inside `dist/packages/pieces/${name}`from Activepieces Platform Admin -> Pieces Manage Pieces # Show/Hide Pieces Source: https://www.activepieces.com/docs/embedding/customize-pieces If you would like to only show specific pieces to your embedding users, we recommend you do the following: Tag the pieces you would like to show to your user by going to **Platform Admin -> Setup -> Pieces**, selecting the pieces you would like to tag and hit **Apply Tags** Bulk Tag You need to specify the tags of pieces in the token, check how to generate token in [provisioning users](./provision-users). You should specify the `pieces` claim like this: ```json theme={null} { /// Other claims "piecesFilterType": "ALLOWED", "piecesTags": [ "free" ] } ``` Each time the token is used by the embedding SDK, it will sync all pieces with these tags to the token's project. The project will only contain the pieces that contain these tags. # Embed Builder Source: https://www.activepieces.com/docs/embedding/embed-builder This documentation explains how to embed the Activepieces iframe inside your application and customize it. ## Configure SDK Adding the embedding SDK script will initialize an object in your window called `activepieces`, which has a method called `configure` that you should call after the container has been rendered. The following scripts shouldn't contain the `async` or `defer` attributes. These steps assume you have already generated a JWT token from the backend. If not, please check the [provision-users](./provision-users) page. ```html theme={null} ``` `configure` returns a promise which is resolved after authentication is done. Please check the [navigation](./navigation) section, as it's very important to understand how navigation works and how to supply an auto-sync experience. **Configure Parameters:** | Parameter Name | Required | Type | Description | | ------------------------------------------ | -------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | instanceUrl | ✅ | string | The url of the instance hosting Activepieces, could be [https://cloud.activepieces.com](https://cloud.activepieces.com) if you are a cloud user. | | jwtToken | ✅ | string | The jwt token you generated to authenticate your users to Activepieces. | | prefix | ❌ | string | Some customers have an embedding prefix, like this `/`. For example if the prefix is `/automation` and the Activepieces url is `/flows` the full url would be `/automation/flows`. | | embedding.containerId | ❌ | string | The html element's id that is going to be containing Activepieces's iframe. | | embedding.builder.disableNavigation | ❌ | boolean \| `keep_home_button_only` | Hides the folder name, home button (if not set to [`keep_home_button_only`](./sdk-changelog#20%2F05%2F2025-0-4-0)) and delete option in the builder, by default it is false. | | embedding.builder.hideFlowName | ❌ | boolean | Hides the flow name and flow actions dropdown in the builder's header, by default it is false. | | embedding.builder.homeButtonClickedHandler | ❌ | `()=>void` | Callback that stops home button from navigating to dashboard and overrides it with this handler (added in [0.4.0](./sdk-changelog#20%2F05%2F2025-0-4-0)) | | embedding.builder.homeButtonIcon | ❌ | `logo` \| `back` | if set to **`back`** the tooltip shown on hovering the home button is removed (added in [0.5.0](./sdk-changelog#03%2F07%2F2025-0-5-0)) | | embedding.dashboard.hideSidebar | ❌ | boolean | Controls the visibility of the sidebar in the dashboard, by default it is false. | | embedding.dashboard.hideFlowsPageNavbar | ❌ | boolean | Controls the visibility of the navbar showing flows,issues and runs above the flows table in the dashboard, by default it is false. (added in [0.6.0](./sdk-changelog#07%2F07%2F2025-0-6-0)) | | embedding.dashboard.hidePageHeader | ❌ | boolean | Hides the page header in the dashboard by default it is false. (added in [0.8.0](./sdk-changelog#09%2F21%2F2025-0-8-0)) | | embedding.hideFolders | ❌ | boolean | Hides all things related to folders in both the flows table and builder by default it is false. | | embedding.styling.fontUrl | ❌ | string | The url of the font to be used in the embedding, by default it is `https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap`. | | embedding.styling.fontFamily | ❌ | string | The font family to be used in the embedding, by default it is `Roboto`. | | embedding.styling.mode | ❌ | `light` \| `dark` | Controls light/dark mode (added in [0.5.0](./sdk-changelog#03%2F07%2F2025-0-5-0)) | | embedding.hideExportAndImportFlow | ❌ | boolean | Hides the option to export or import flows (added in [0.4.0](./sdk-changelog#20%2F05%2F2025-0-4-0)) | | embedding.hideDuplicateFlow | ❌ | boolean | Hides the option to duplicate a flow (added in [0.5.0](./sdk-changelog#03%2F07%2F2025-0-5-0)) | | embedding.locale | ❌ | `en` \| `nl` \| `de` \| `fr` \| `es` \| `ja` \| `zh` \| `pt` \| `zh-TW` \| `ru` \| | it takes [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) locale codes (added in [0.5.0](./sdk-changelog#03%2F07%2F2025-0-5-0)) | | navigation.handler | ❌ | `({route:string}) => void` | This callback will be triggered each time a route in Activepieces changes, you can read more about it [here](/embedding/navigation) | For the font to be loaded, you need to set both the `fontUrl` and `fontFamily` properties. If you only set one of them, the default font will be used. The default font is `Roboto`. The font weights we use are the default font-weights from [tailwind](https://tailwindcss.com/docs/font-weight). # Create/Update Connections Source: https://www.activepieces.com/docs/embedding/embed-connections **Requirements:** * Activepieces version 0.34.5 or higher * SDK version 0.3.2 or higher "connectionName" is the externalId of the connection (you can get it by hovering the connection name in the connections table).
We kept the same parameter name for backward compatibility, anyone upgrading their instance from \< 0.35.1, will not face issues in that regard.
**Breaking Change:**

If your Activepieces instance version is \< 0.45.0 and (you are using the connect method from the embed sdk, and need the connection externalId to be returned after the user creates it OR if you want to reconnect a specific connection with an externalId), you must upgrade your instance to >= 0.45.0
* You can use the embedded SDK in your SaaS to allow your users to create connections and store them in Activepieces. Follow the instructions in the [Embed Builder](./embed-builder). After initializing the SDK, you will have access to a property called `activepieces` inside your `window` object. Call its `connect` method to open a new connection dialog as follows. ```html theme={null} ``` **Connect Parameters:** | Parameter Name | Required | Type | Description | | -------------- | -------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | pieceName | ✅ | string | The name of the piece you want to create a connection for. | | connectionName | ❌ | string | The external Id of the connection (you can get it by hovering the connection name in the connections table), when provided the connection created/upserted will use this as the external Id and display name. | | newWindow | ❌ | \{ width?: number, height?: number, top?: number, left?: number } | If set the connection dialog will be opened in a new window instead of an iframe taking the full page. | **Connect Result** The `connect` method returns a `promise` that resolves to the following: ```ts theme={null} { connection?: { id: string, name: string } } ``` `name` is the externalId of the connection. `connection` is undefined if the user closes the dialog and doesn't create a connection. You can use the `connections` piece in the builder to retrieve the created connection using its name. Connections in Builder Connections in Builder # Navigation Source: https://www.activepieces.com/docs/embedding/navigation By default, navigating within your embedded instance of Activepieces doesn't affect the client's browser history or viewed URL. Activepieces only provide a **handler**, that trigger on every route change in the **iframe**. ## Automatically Sync URL You can use the following snippet when configuring the SDK, which will implement a handler that syncs the Activepieces iframe with your browser: The following snippet listens when the user clicks backward, so it syncs the route back to the iframe using `activepieces.navigate` and in the handler, it updates the URL of the browser. ```js theme={null} const instanceUrl = 'YOUR_INSTANCE_URL'; const jwtToken = 'YOUR_GENERATED_JWT_TOKEN'; const containerId = 'YOUR_CONTAINER_ID'; activepieces.configure({ instanceUrl, jwtToken, embedding: { containerId, builder: { disableNavigation: false, hideFlowName: false }, dashboard: { hideSidebar: false }, hideFolders: false, navigation: { handler: ({ route }) => { //route can include search params at the end of it if (!window.location.href.endsWith(route)) { window.history.pushState({}, "", window.location.origin + route); } } } }, }); window.addEventListener("popstate", () => { const route = activepieces.extractActivepiecesRouteFromUrl({ vendorUrl: window.location.href }); activepieces.navigate({ route }); }); ``` ## Navigate Method If you use `activepieces.navigate({ route: '/flows' })` this will tell the embedded sdk where to navigate to. Here is the list for routes the sdk can navigate to: | Route | Description | | ------------------- | ------------------------------ | | `/flows` | Flows table | | `/flows/{flowId}` | Opens up a flow in the builder | | `/runs` | Runs table | | `/runs/{runId}` | Opens up a run in the builder | | `/connections` | Connections table | | `/tables` | Tables table | | `/tables/{tableId}` | Opens up a table | | `todos` | Todos table | | `todos/{todoId}` | Opens up a todo | ## Navigate to Initial Route You can call the `navigate` method after initializing the sdk using the `configure` sdk: ```js theme={null} const flowId = '1234'; const instanceUrl = 'YOUR_INSTANCE_URL'; const jwtToken = 'YOUR_GENERATED_JWT_TOKEN'; activepieces.configure({ instanceUrl, jwtToken, }).then(() => { activepieces.navigate({ route: `/flows/${flowId}` }) }); ``` # Overview Source: https://www.activepieces.com/docs/embedding/overview Understanding how embedding works This section provides an overview of how to embed the Activepieces builder in your application and automatically provision the user. The embedding process involves the following steps: Generate a JSON Web Token (JWT) to identify your customer and pass it to the SDK, read more [here](./provision-users). You can use the SDK to embed and customize Activepieces in your SaaS, read more [here](./embed-builder). Here is an example of how it looks like in one of the SaaS that embed Activepieces: Embedding Example In case, you need to gather connections from your users in your SaaS. You can do this with the SDK. Find more info [here](./embed-connections). If you are looking for a way to communicate between Activpieces and the SaaS embedding it through a piece, we recommend you check the [custom property doc](/build-pieces/piece-reference/properties#custom-property-beta) # Predefined Connection Source: https://www.activepieces.com/docs/embedding/predefined-connection Use predefined connections to allow users to access your piece in the embedded app without re-entering authentication credentials. The high-level steps are: * Create a global connection for a project using the API in the platform admin. Only platform admins can edit or delete global connections. * (Optional) Hide the connections dropdown in the piece settings. ### Prerequisites * [Run the Enterprise Edition](/handbook/engineering/playbooks/run-ee) * [Create your piece](/build-pieces/building-pieces/overview). Later we will customize the piece logic to use predefined connections. ### Create a Predefined Connection Go to **Platform Admin → Security → API Keys** and create an API key. Save it for use in the next step. Create API Key Add the following snippet to your backend to create a global connection each time you generate the JWT token. The snippet does the following: * Create Project If it doesn't exist. * Create a global connection for the project with certain naming convention. ```js theme={null} const apiKey = 'YOUR_API_KEY'; const instanceUrl = 'https://cloud.activepieces.com'; // The name of the user / organization in your SAAS const externalProjectId = 'org_1234'; const pieceName = '@activepieces/piece-gelato'; // This will depend on what your piece auth type is, can be one of this ['PLATFORM_OAUTH2','SECRET_TEXT','BASIC_AUTH','CUSTOM_AUTH'] const pieceAuthType = "CUSTOM_AUTH" const connectionProps = { // Fill in the props required by your piece's auth } const { id: projectId, externalId } = await getOrCreateProject({ projectExternalId: externalProjectId, apiKey, instanceUrl, }); await createGlobalConnection({ projectId, externalProjectId, apiKey, instanceUrl, pieceName, props, pieceAuthType }); ``` Implementation: ```js theme={null} async function getOrCreateProject({ projectExternalId, apiKey, instanceUrl, }: { projectExternalId: string, apiKey: string, instanceUrl: string }): Promise<{ id: string, externalId: string }> { const projects = await fetch(`${instanceUrl}/api/v1/projects?externalId=${projectExternalId}`, { method: 'GET', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, }) .then(response => response.json()) .then(data => data.data) .catch(err => { console.error('Error fetching projects:', err); return []; }); if (projects.length > 0) { return { id: projects[0].id, externalId: projects[0].externalId }; } const newProject = await fetch(`${instanceUrl}/api/v1/projects`, { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ displayName: projectExternalId, metadata: {}, externalId: projectExternalId }) }) .then(response => response.json()) .catch(err => { console.error('Error creating project:', err); throw err; }); return { id: newProject.id, externalId: newProject.externalId }; } async function createGlobalConnection({ projectId, externalProjectId, apiKey, instanceUrl, pieceName, props, pieceAuthType }: { projectId: string, externalProjectId: string, apiKey: string, instanceUrl: string, pieceName: string, props: Record, pieceAuthType }) { const displayName = 'Gelato Connection'; const connectionExternalId = 'gelato_' + externalProjectId; return fetch(`${instanceUrl}/api/v1/global-connections`, { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ displayName, pieceName, metadata: {}, type: pieceAuthType, value: { type: pieceAuthType, props }, scope: 'PLATFORM', projectIds: [projectId], externalId: connectionExternalId }) }); } ``` ### Hide the Connections Dropdown (Optional) Wherever you call `createTrigger` or `createAction` set `requireAuth` to `false`, this will hide the connections dropdown in the piece settings in the builder, next we need to fetch it based on a naming convention. Here is example how you can fetch the connection value based on naming convention, make sure this naming convention is followed when creating a global connection. ```js theme={null} import { ConnectionsManager, Property, TriggerStrategy } from "@activepieces/pieces-framework"; import { createTrigger } from "@activepieces/pieces-framework"; import { isNil } from "@activepieces/shared"; // Add this import from the index.ts file, where it contains the definition of the auth object. import { auth } from '../..'; const fetchConnection = async ( connections: ConnectionsManager, projectExternalId: string | undefined, ): Promise> => { if (isNil(projectExternalId)) { throw new Error('This project is missing an external id'); } // the naming convention here is gelato_projectExternalId const connection = await connections.get(`gelato_${projectExternalId}`); if (isNil(connection)) { throw new Error(`Connection not found for project ${projectExternalId}`); } return connection as PiecePropValueSchema; }; export const newFlavorCreated = createTrigger({ requireAuth: false, name: 'newFlavorCreated', displayName: 'new flavor created', description: 'triggers when a new icecream flavor is created.', props: { dropdown: Property.Dropdown({ displayName: 'Dropdown', required: true, refreshers: [], options: async (_, { connections, project }) => { const connection = await fetchConnection(connections, (await project.externalId())); // your logic return { options: [{ label: 'test', value: 'test' }] } } }) }, sampleData: {}, type: TriggerStrategy.POLLING, async test({connections,project}) { const connection = await fetchConnection(connections, (await project.externalId())); // use the connection with your own logic return [] }, async onEnable({connections,project}) { const connection = await fetchConnection(connections, (await project.externalId())); // use the connection with your own logic }, async onDisable({connections,project}) { const connection = await fetchConnection(connections, (await project.externalId())); // use the connection with your own logic }, async run({connections,project}) { const connection = await fetchConnection(connections, (await project.externalId())); // use the connection with your own logic return [] }, }); ``` # Provision Users Source: https://www.activepieces.com/docs/embedding/provision-users Automatically authenticate your SaaS users to your Activepieces instance ## Overview In Activepieces, there are **Projects** and **Users**. Each project is provisioned with their corresponding workspace, project, or team in your SaaS. The users are then mapped to the respective users in Activepieces. To achieve this, the backend will generate a signed token that contains all the necessary information to automatically create a user and project. If the user or project already exists, it will skip the creation and log in the user directly. You can generate a signing key by going to **Platform Settings -> Signing Keys -> Generate Signing Key**. This will generate a public and private key pair. The public key will be used by Activepieces to verify the signature of the JWT tokens you send. The private key will be used by you to sign the JWT tokens. Create Signing Key Please store your private key in a safe place, as it will not be stored in Activepieces. The signing key will be used to generate JWT tokens for the currently logged-in user on your website, which will then be sent to the Activepieces Iframe as a query parameter to authenticate the user and exchange the token for a longer lived token. To generate these tokens, you will need to add code in your backend to generate the token using the RS256 algorithm, so the JWT header would look like this: To obtain the `SIGNING_KEY_ID`, refer to the signing key table and locate the value in the first column. Signing Key ID ```json theme={null} { "alg": "RS256", "typ": "JWT", "kid": "SIGNING_KEY_ID" } ``` The signed tokens must include these claims in the payload: ```json theme={null} { "version": "v3", "externalUserId": "user_id", "externalProjectId": "user_project_id", "firstName": "John", "lastName": "Doe", "role": "EDITOR", "piecesFilterType": "NONE", "exp": 1856563200, "tasks": 50000, "aiCredits": 250 } ``` | Claim | Description | | ------------------ | -------------------------------------------------------------------------------------- | | externalUserId | Unique identification of the user in **your** software | | externalProjectId | Unique identification of the user's project in **your** software | | projectDisplayName | Display name of the user's project | | firstName | First name of the user | | lastName | Last name of the user | | role | Role of the user in the Activepieces project (e.g., **EDITOR**, **VIEWER**, **ADMIN**) | | exp | Expiry timestamp for the token (Unix timestamp) | | piecesFilterType | Customize the project pieces, check [customize pieces](/embedding/customize-pieces) | | piecesTags | Customize the project pieces, check [customize pieces](/embedding/customize-pieces) | | tasks | Customize the tasks limit for your user's project | | aiCredits | Customize the ai credits limit for your user's project | You can use any JWT library to generate the token. Here is an example using the jsonwebtoken library in Node.js: **Friendly Tip #1**: You can also use this [tool](https://dinochiesa.github.io/jwt/) to generate a quick example. **Friendly Tip #2**: Make sure the expiry time is very short, as it's a temporary token and will be exchanged for a longer-lived token. ```javascript Node.js theme={null} const jwt = require('jsonwebtoken'); // JWT NumericDates specified in seconds: const currentTime = Math.floor(Date.now() / 1000); let token = jwt.sign( { version: "v3", externalUserId: "user_id", externalProjectId: "user_project_id", firstName: "John", lastName: "Doe", role: "EDITOR", piecesFilterType: "NONE", exp: currentTime + (60 * 60), // 1 hour from now }, process.env.ACTIVEPIECES_SIGNING_KEY, { algorithm: "RS256", header: { kid: signingKeyID, // Include the "kid" in the header }, } ); ``` Once you have generated the token, please check the embedding docs to know how to embed the token in the iframe. # SDK Changelog Source: https://www.activepieces.com/docs/embedding/sdk-changelog A log of all notable changes to Activepieces SDK **Breaking Change:**

If your Activepieces image version is \< 0.45.0 and (you are using the connect method from the embed SDk, and need the connection externalId to be returned after the user creates it OR if you want to reconnect a specific connection with an externalId), you must upgrade your Activepieces image to >= 0.45.0
Between Acitvepieces image version 0.32.1 and 0.46.4 the navigation handler was including the project id in the path, this might have broken implementation logic for people using the navigation handler, this has been fixed from 0.46.5 and onwards, the handler won't show the project id prepended to routes. Change log format: MM/DD/YYYY (version) ### 10/27/2025 (0.8.1) * SDK URL: [https://cdn.activepieces.com/sdk/embed/0.8.1.js](https://cdn.activepieces.com/sdk/embed/0.8.1.js) * Fixed a bug where if you didn't start your navigation route with '/' it would redirect you to '/flows' ### 09/21/2025 (0.8.0) * SDK URL: [https://cdn.activepieces.com/sdk/embed/0.8.0.js](https://cdn.activepieces.com/sdk/embed/0.8.0.js) * This version requires you to **upgrade Activepieces to [0.70.0](https://github.com/activepieces/activepieces/releases/tag/0.70.0)**. * Removed `embedding.dashboard.hideSettings`. * Added `embedding.dashboard.hidePageHeader` parameter to the [configure](./embed-builder#configure-parameters) method **(value: true | false)**. ### 07/30/2025 (0.7.0) * SDK URL: [https://cdn.activepieces.com/sdk/embed/0.7.0.js](https://cdn.activepieces.com/sdk/embed/0.7.0.js) * This version requires you to **upgrade Activepieces to [0.66.7](https://github.com/activepieces/activepieces/releases/tag/0.66.7)** * Added `embedding.dashboard.hideSettings` parameter to the [configure](./embed-builder#configure-parameters) method **(value: true | false)**. ### 07/07/2025 (0.6.0) * SDK URL: [https://cdn.activepieces.com/sdk/embed/0.6.0.js](https://cdn.activepieces.com/sdk/embed/0.6.0.js) * This version requires you to **upgrade Activepieces to [0.66.1](https://github.com/activepieces/activepieces/releases/tag/0.66.1)** * Added `embedding.dashboard.hideFlowsPageNavbar` parameter to the [configure](./embed-builder#configure-parameters) method **(value: true | false)**. * **(Breaking Change)** `embedding.dashboard.hideSidebar` used to hide the navbar above the flows table in the dashboard now it relies on `embedding.dashboard.hideFlowsPageNavbar`. ### 03/07/2025 (0.5.0) * SDK URL: [https://cdn.activepieces.com/sdk/embed/0.5.0.js](https://cdn.activepieces.com/sdk/embed/0.5.0.js) * This version requires you to **upgrade Activepieces to [0.64.2](https://github.com/activepieces/activepieces/releases/tag/0.64.2)** * Added `embedding.hideDuplicateFlow` parameter to the [configure](./embed-builder#configure-parameters) method **(value: true | false)**. * Added `embedding.builder.homeButtonIcon` parameter to the [configure](./embed-builder#configure-parameters) method **(value: 'logo' | 'back')**, if set to **'back'** the tooltip shown on hovering the home button is removed. * Added `embedding.locale` parameter to the [configure](./embed-builder#configure-parameters) method, it takes [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) locale codes, here are the ones supported: **('en' | 'nl' | 'it' | 'de' | 'fr' | 'bg' | 'uk' | 'hu' | 'es' | 'ja' | 'id' | 'vi' | 'zh' | 'pt')** * Added `embedding.styling.mode` parameter to [configure](./embed-builder#configure-parameters) method **(value: 'light' | 'dark')** * **(Breaking Change)** Removed `embedding.builder.hideLogo` parameter from the [configure](./embed-builder#configure-parameters) method. * **(Breaking Change)** Removed MCP methods from sdk. ### 17/06/2025 (0.5.0-rc.1) * SDK URL: [https://cdn.activepieces.com/sdk/embed/0.5.0-rc.1.js](https://cdn.activepieces.com/sdk/embed/0.5.0-rc.1.js) * This version requires you to **upgrade Activepieces to [0.64.0-rc.0](https://github.com/activepieces/activepieces/pkgs/container/activepieces/438888138?tag=0.64.0-rc.0)** * Revert back the `prefix` parameter from the [configure](./embed-builder#configure-parameters) method. ### 16/06/2025 (0.5.0-rc.0) * SDK URL: [https://cdn.activepieces.com/sdk/embed/0.5.0-rc.0.js](https://cdn.activepieces.com/sdk/embed/0.5.0-rc.0.js) * This version requires you to **upgrade Activepieces to [0.64.0-rc.0](https://github.com/activepieces/activepieces/pkgs/container/activepieces/438888138?tag=0.64.0-rc.0)** * Added `embedding.hideDuplicateFlow` parameter to the [configure](./embed-builder#configure-parameters) method **(value: true | false)**. * Added `embedding.builder.homeButtonIcon` parameter to the [configure](./embed-builder#configure-parameters) method **(value: 'logo' | 'back')**, if set to **'back'** the tooltip shown on hovering the home button is removed. * Added `embedding.locale` parameter to the [configure](./embed-builder#configure-parameters) method, it takes [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) locale codes, here are the ones supported: **('en' | 'nl' | 'it' | 'de' | 'fr' | 'bg' | 'uk' | 'hu' | 'es' | 'ja' | 'id' | 'vi' | 'zh' | 'pt')** * Added `embedding.styling.mode` parameter to [configure](./embed-builder#configure-parameters) method **(value: 'light' | 'dark')** * **(Breaking Change)** Removed `prefix` parameter from the [configure](./embed-builder#configure-parameters) method. * **(Breaking Change)** Removed `embedding.builder.hideLogo` parameter from the [configure](./embed-builder#configure-parameters) method. ### 26/05/2025 (0.4.1) * Fixed an issue where sometimes the embed HTML file was getting cached. ### 20/05/2025 (0.4.0) \-- Note: we didn't consider adding optional new parameters as a breaking change so we were bumping the patch version, but that was wrong and we will begin bumping the minor version for those changes from now on, and patch version will only get bumped for bug fixes. * This version requires you to update Activepieces to 0.56.0 * Added `embedding.hideExportAndImportFlow` parameter to the [configure](./embed-builder#configure-parameters) method. * Added new possible value to the configure method param `embed.builder.disableNavigation` which is "keep\_home\_button\_only" that keeps only the home button and hides the folder name with the delete flow action. * Added new param to the configure method `embed.builder.homeButtonClickedHandler`, that overrides the navigation behaviour on clicking the home button. ### 17/04/2025 (0.3.7) * Added MCP methods to update MCP configurations. ### 16/04/2025 (0.3.6) * Added the [request](./sdk-server-requests) method which allows you to call our backend API. ### 24/2/2025 (0.3.5) * Added a new parameter to the connect method to make the connection dialog a popup instead of an iframe taking the full page. * Fixed a bug where the returned promise from the connect method was always resolved to \{connection: undefined} * Now when you use the connect method with the "connectionName" parameter, the user will reconnect to the connection with the matching externalId instead of creating a new one. ### 04/02/2025 (0.3.4) * This version requires you to update Activepieces to 0.41.0 * Adds the ability to pass font family name and font url to the embed sdk ### 26/01/2025 (0.3.3) * This version requires you to update Activepieces to 0.39.8 * activepieces.configure method was being resolved before the user was authenticated, this is fixed now, so you can use activepieces.navigate method to navigate to your desired initial route. ### 04/12/2024 (0.3.0) * add custom navigation handler ([#4500](https://github.com/activepieces/activepieces/pull/4500)) * allow passing a predefined name for connection in connect method ([#4485](https://github.com/activepieces/activepieces/pull/4485)) * add changelog ([#4503](https://github.com/activepieces/activepieces/pull/4503)) # API Requests Source: https://www.activepieces.com/docs/embedding/sdk-server-requests Send requests to your Activepieces instance from the embedded app **Requirements:** * Activepieces version 0.34.5 or higher * SDK version 0.3.6 or higher You can use the embedded SDK to send requests to your instance and retrieve data. Follow the instructions in the [Embed Builder](./embed-builder) to initialize the SDK. ```html theme={null} ``` **Request Parameters:** | Parameter Name | Required | Type | Description | | -------------- | -------- | ---------------------- | --------------------------------------------------------------------------------------------------- | | path | ✅ | string | The path within your instance you want to hit (we prepend the path with your\_instance\_url/api/v1) | | method | ✅ | string | The http method to use 'GET', 'POST','PUT', 'DELETE', 'OPTIONS', 'PATCH' and 'HEAD | | body | ❌ | JSON object | The json body of your request | | queryParams | ❌ | Record\ | The query params to include in your request | # Delete Connection Source: https://www.activepieces.com/docs/endpoints/connections/delete DELETE /v1/app-connections/{id} Delete an app connection # List Connections Source: https://www.activepieces.com/docs/endpoints/connections/list GET /v1/app-connections List app connections # Connection Schema Source: https://www.activepieces.com/docs/endpoints/connections/schema # Upsert Connection Source: https://www.activepieces.com/docs/endpoints/connections/upsert POST /v1/app-connections Upsert an app connection based on the app name # Get Flow Run Source: https://www.activepieces.com/docs/endpoints/flow-runs/get GET /v1/flow-runs/{id} Get Flow Run # List Flows Runs Source: https://www.activepieces.com/docs/endpoints/flow-runs/list GET /v1/flow-runs List Flow Runs # Flow Run Schema Source: https://www.activepieces.com/docs/endpoints/flow-runs/schema # Create Flow Template Source: https://www.activepieces.com/docs/endpoints/flow-templates/create POST /v1/flow-templates # Delete Flow Template Source: https://www.activepieces.com/docs/endpoints/flow-templates/delete DELETE /v1/flow-templates/{id} # Get Flow Template Source: https://www.activepieces.com/docs/endpoints/flow-templates/get GET /v1/flow-templates/{id} # List Flow Templates Source: https://www.activepieces.com/docs/endpoints/flow-templates/list GET /v1/flow-templates List flow templates. This endpoint is deprecated, use /v1/templates instead. # Flow Template Schema Source: https://www.activepieces.com/docs/endpoints/flow-templates/schema # Create Flow Source: https://www.activepieces.com/docs/endpoints/flows/create POST /v1/flows Create a flow # Delete Flow Source: https://www.activepieces.com/docs/endpoints/flows/delete DELETE /v1/flows/{id} Delete a flow # Get Flow Source: https://www.activepieces.com/docs/endpoints/flows/get GET /v1/flows/{id} Get a flow by id # List Flows Source: https://www.activepieces.com/docs/endpoints/flows/list GET /v1/flows List flows # Flow Schema Source: https://www.activepieces.com/docs/endpoints/flows/schema # Apply Flow Operation Source: https://www.activepieces.com/docs/endpoints/flows/update POST /v1/flows/{id} Apply an operation to a flow # Create Folder Source: https://www.activepieces.com/docs/endpoints/folders/create POST /v1/folders Create a new folder # Delete Folder Source: https://www.activepieces.com/docs/endpoints/folders/delete DELETE /v1/folders/{id} Delete a folder # Get Folder Source: https://www.activepieces.com/docs/endpoints/folders/get GET /v1/folders/{id} Get a folder by id # List Folders Source: https://www.activepieces.com/docs/endpoints/folders/list GET /v1/folders List folders # Folder Schema Source: https://www.activepieces.com/docs/endpoints/folders/schema # Update Folder Source: https://www.activepieces.com/docs/endpoints/folders/update POST /v1/folders/{id} Update an existing folder # Configure Source: https://www.activepieces.com/docs/endpoints/git-repos/configure POST /v1/git-repos Upsert a git repository information for a project. # Git Repos Schema Source: https://www.activepieces.com/docs/endpoints/git-repos/schema # Delete Global Connection Source: https://www.activepieces.com/docs/endpoints/global-connections/delete DELETE /v1/global-connections/{id} # List Global Connections Source: https://www.activepieces.com/docs/endpoints/global-connections/list GET /v1/global-connections # Global Connection Schema Source: https://www.activepieces.com/docs/endpoints/global-connections/schema # Update Global Connection Source: https://www.activepieces.com/docs/endpoints/global-connections/update POST /v1/global-connections/{id} # Upsert Global Connection Source: https://www.activepieces.com/docs/endpoints/global-connections/upsert POST /v1/global-connections # Overview Source: https://www.activepieces.com/docs/endpoints/overview API keys are generated under the platform dashboard at this moment to manage multiple projects, which is only available in the Platform and Enterprise editions, Please contact [sales@activepieces.com](mailto:sales@activepieces.com) for more information. ### Authentication: The API uses "API keys" to authenticate requests. You can view and manage your API keys from the Platform Dashboard. After creating the API keys, you can pass the API key as a Bearer token in the header. Example: `Authorization: Bearer {API_KEY}` ### Pagination All endpoints use seek pagination, to paginate through the results, you can provide the `limit` and `cursor` as query parameters. The API response will have the following structure: ```json theme={null} { "data": [], "next": "string", "previous": "string" } ``` * **`data`**: Holds the requested results or data. * **`next`**: Provides a starting cursor for the next set of results, if available. * **`previous`**: Provides a starting cursor for the previous set of results, if applicable. # Install Piece Source: https://www.activepieces.com/docs/endpoints/pieces/install POST /v1/pieces Add a piece to a platform # Piece Schema Source: https://www.activepieces.com/docs/endpoints/pieces/schema # Delete Project Member Source: https://www.activepieces.com/docs/endpoints/project-members/delete DELETE /v1/project-members/{id} # List Project Member Source: https://www.activepieces.com/docs/endpoints/project-members/list GET /v1/project-members # Project Member Schema Source: https://www.activepieces.com/docs/endpoints/project-members/schema # Create Project Release Source: https://www.activepieces.com/docs/endpoints/project-releases/create POST /v1/project-releases # Project Release Schema Source: https://www.activepieces.com/docs/endpoints/project-releases/schema # Create Project Source: https://www.activepieces.com/docs/endpoints/projects/create POST /v1/projects # Delete Project Source: https://www.activepieces.com/docs/endpoints/projects/delete DELETE /v1/projects/{id} # List Projects Source: https://www.activepieces.com/docs/endpoints/projects/list GET /v1/projects # Project Schema Source: https://www.activepieces.com/docs/endpoints/projects/schema # Update Project Source: https://www.activepieces.com/docs/endpoints/projects/update POST /v1/projects/{id} # Queue Stats Source: https://www.activepieces.com/docs/endpoints/queue-metrics/metrics GET /v1/queue-metrics Get metrics # Get Sample Data Source: https://www.activepieces.com/docs/endpoints/sample-data/get GET /v1/sample-data # Delete User Invitation Source: https://www.activepieces.com/docs/endpoints/user-invitations/delete DELETE /v1/user-invitations/{id} # List User Invitations Source: https://www.activepieces.com/docs/endpoints/user-invitations/list GET /v1/user-invitations # User Invitation Schema Source: https://www.activepieces.com/docs/endpoints/user-invitations/schema # Send User Invitation (Upsert) Source: https://www.activepieces.com/docs/endpoints/user-invitations/upsert POST /v1/user-invitations Send a user invitation to a user. If the user already has an invitation, the invitation will be updated. # List Users Source: https://www.activepieces.com/docs/endpoints/users/list GET /v1/users List users # User Schema Source: https://www.activepieces.com/docs/endpoints/users/schema # Update User Source: https://www.activepieces.com/docs/endpoints/users/update POST /v1/users/{id} Update user # Building Flows Source: https://www.activepieces.com/docs/flows/building-flows Flow consists of two parts, trigger and actions ## Trigger The flow's starting point determines its frequency of execution. There are various types of triggers available, such as Schedule Trigger, Webhook Trigger, or Event Trigger based on specific service. ## Action Actions come after the flow and control what occurs when the flow is activated, like running code or communicating with other services. In real-life scenario: Flow Parts # Debugging Runs Source: https://www.activepieces.com/docs/flows/debugging-runs Ensuring your business automations are running properly You can monitor each run that results from an enabled flow: 1. Go to the Dashboard, click on **Runs**. 2. Find the run that you're looking for, and click on it. 3. You will see the builder in a view-only mode, each step will show a ✅ or a ❌ to indicate its execution status. 4. Click on any of these steps, you will see the **input** and **output** in the **Run Details** panel. The debugging experience looks like this: Debugging Business Automations # Technical Limits Source: https://www.activepieces.com/docs/flows/known-limits Technical limits for Activepieces execution ### Execution Limits * **Flow Execution Time**\ Maximum: **600 seconds (10 minutes)**\ Flows exceeding this limit will be marked as timed out. * **Memory Usage**\ Maximum: **1 GB RAM**\ (Self hosted can be configured via `AP_SANDBOX_MEMORY_LIMIT`) The memory usage is measured for the entire Node.js process running the flow. There is approximately 300 MB of overhead for a warm process with pieces already loaded. **Note 1:** Flows paused by steps like **Wait for Approval** or **Delay** do **not** count toward the 600-second limit. **Note 2:** To handle longer processes, split them into multiple flows.\ For example: * Have one flow call another via **webhook**. * Process smaller **batches of items** in separate flows. *** ### File Storage Limits Files from actions or triggers are stored in the database/S3 to support retries for certain steps. * **Maximum File Size**: **10 MB**\ (Configurable via `AP_MAX_FILE_SIZE_MB`, default: **4 MB**) *** ### Key / Value Storage Limits Some pieces use the built-in Activepieces key store (e.g., **Store Piece**, **Queue Piece**). * **Maximum Key Length**: **128 characters** * **Maximum Value Size**: **512 KB** # Passing Data Source: https://www.activepieces.com/docs/flows/passing-data Using data from previous steps in the current one ## Data flow Any Activepieces flow is a vertical diagram that **starts with a trigger step** followed by **any number of action steps**. Steps are connected vertically. Data flows from parent steps to the children. Children steps have access to the output data of the parent steps. ## Example Steps