|
| 1 | +--- |
| 2 | +title: Build your Plane Integration app |
| 3 | +sidebarTitle: Build your Plane Integration app |
| 4 | +description: Step-by-step guide for developers to build and integrate an app with Plane.so using OAuth-based authentication and authorization workflow. |
| 5 | +--- |
| 6 | + |
| 7 | +This guide provides step-by-step instructions for developers to build and integrate an app with Plane.so using an OAuth-based authentication and authorization workflow. |
| 8 | + |
| 9 | +## Introduction |
| 10 | + |
| 11 | +Plane.so supports OAuth 2.0 for secure authentication and authorization of third-party applications. This ensures that apps can request and obtain access tokens on behalf of users, enabling seamless integration while maintaining security standards. |
| 12 | + |
| 13 | +## Prerequisites |
| 14 | + |
| 15 | +* A Plane.so workspace. |
| 16 | +* Access to Plane.so developer portal. |
| 17 | +* Familiarity with OAuth 2.0 concepts (authorization code flow). |
| 18 | +* A backend server to handle OAuth token exchange. |
| 19 | + |
| 20 | +## High-Level Workflow |
| 21 | + |
| 22 | +1. **Register your app on Plane.so developer portal** |
| 23 | +2. **Implement OAuth authorization code flow** |
| 24 | +3. **Obtain and store access tokens securely** |
| 25 | +4. **Make authenticated API requests to Plane.so** |
| 26 | +5. **Handle token refresh** |
| 27 | + |
| 28 | +## Registering Your App |
| 29 | + |
| 30 | +To build an OAuth application with Plane.so: |
| 31 | + |
| 32 | +1. Navigate to `https://app.plane.so/<workspace_slug>/settings/applications/`. |
| 33 | +2. Click on the **Build your own** button. |
| 34 | +3. Fill out the form with the required details: |
| 35 | + |
| 36 | + * **Redirect URIs**: Provide the URIs where Plane.so will send the authorization code. |
| 37 | + * **Contact Details**: Add your email or other contact information. |
| 38 | + * **Webhook URL Endpoint**: Update this with your service's webhook endpoint. Plane.so will send webhooks for all changes that happen in the installed workspace. |
| 39 | + * **Organization Details**: Include contact email, privacy policy URL, terms of service URL, and any other relevant information. This helps Plane.so validate and approve your application for listing in the marketplace. |
| 40 | +4. If you're building an agent (with or without using Plane's ADK) capable of performing operations when assigned or mentioned, enable the **Is Mentionable** checkbox during app creation. |
| 41 | +5. Once the app is created, securely store the **Client ID** and **Client Secret**. You will need these credentials to interact with Plane.so's API during the OAuth flow and for making authenticated API requests. |
| 42 | + |
| 43 | +## Authentication Setup |
| 44 | + |
| 45 | +### Generating Consent URL |
| 46 | + |
| 47 | +Before handling types of authentication, if your app manages installation, you must generate the consent (authorization) URL to initiate the OAuth flow. Below is a sample implementation: |
| 48 | + |
| 49 | +```python |
| 50 | +params = { |
| 51 | + "client_id": os.getenv("PLANE_CLIENT_ID"), |
| 52 | + "response_type": "code", |
| 53 | + "redirect_uri": os.getenv("PLANE_REDIRECT_URI"), |
| 54 | + # Optional: include state if needed |
| 55 | +} |
| 56 | + |
| 57 | +consent_url = f"https://api.plane.so/auth/o/authorize-app/?{urlencode(params)}" |
| 58 | +``` |
| 59 | + |
| 60 | +There are two types of authenticated actions your application can perform: |
| 61 | + |
| 62 | +1. **User-authorized actions** — Actions performed on behalf of a user after they grant permission to your app via OAuth. |
| 63 | +2. **App-authorized actions** — Actions that the app can perform independently within the workspace where it is installed (such as responding to webhooks or automation triggers). |
| 64 | + |
| 65 | +We will describe how to configure and use each type in the following sections. |
| 66 | + |
| 67 | +### App-Authorized Actions (Client Credentials Flow) |
| 68 | + |
| 69 | +When the user or admin installs the app, Plane.so will send an `app_installation_id` as part of the callback to the `redirect_uri` provided during consent URL generation. You can use this `app_installation_id` to request a bot token for your app. |
| 70 | + |
| 71 | +#### Example Pseudo-code |
| 72 | + |
| 73 | +```python |
| 74 | +# Prepare basic auth header using client_id and client_secret |
| 75 | +basic_auth = base64encode("client_id:client_secret") |
| 76 | + |
| 77 | +# Prepare request data |
| 78 | +payload = { |
| 79 | + "grant_type": "client_credentials", |
| 80 | + "app_installation_id": app_installation_id |
| 81 | +} |
| 82 | + |
| 83 | +# Make a POST request to fetch bot token |
| 84 | +response = POST( |
| 85 | + url="https://api.plane.so/auth/o/token/", |
| 86 | + headers={"Authorization": f"Basic {basic_auth}", |
| 87 | + "Content-Type": "application/x-www-form-urlencoded"}, |
| 88 | + data=payload |
| 89 | +) |
| 90 | + |
| 91 | +bot_token = response.data['access_token'] |
| 92 | +``` |
| 93 | + |
| 94 | +### User-Authorized Actions (Authorization Code Flow) |
| 95 | + |
| 96 | +In this flow, your app exchanges the `code` received as a query parameter on the callback (to your `redirect_uri`) for an access token and refresh token. The access token is short-lived and must be refreshed using the refresh token when it expires. Both tokens should be securely stored. |
| 97 | + |
| 98 | +#### Example Pseudo-code |
| 99 | + |
| 100 | +```python |
| 101 | +# Exchange authorization code for access and refresh tokens |
| 102 | +payload = { |
| 103 | + "grant_type": "authorization_code", |
| 104 | + "code": code, |
| 105 | + "client_id": client_id, |
| 106 | + "client_secret": client_secret, |
| 107 | + "redirect_uri": redirect_uri |
| 108 | +} |
| 109 | + |
| 110 | +response = POST( |
| 111 | + url="https://api.plane.so/auth/o/token/", |
| 112 | + headers={"Content-Type": "application/x-www-form-urlencoded"}, |
| 113 | + data=payload |
| 114 | +) |
| 115 | + |
| 116 | +if response.success: |
| 117 | + access_token = response.data["access_token"] |
| 118 | + refresh_token = response.data["refresh_token"] |
| 119 | + |
| 120 | + |
| 121 | +# When access token expires, use refresh token to get a new access token |
| 122 | +refresh_payload = { |
| 123 | + "grant_type": "refresh_token", |
| 124 | + "refresh_token": refresh_token, |
| 125 | + "client_id": client_id, |
| 126 | + "client_secret": client_secret |
| 127 | +} |
| 128 | + |
| 129 | +refresh_response = POST( |
| 130 | + url="https://api.plane.so/auth/o/token/", |
| 131 | + headers={"Content-Type": "application/x-www-form-urlencoded"}, |
| 132 | + data=refresh_payload |
| 133 | +) |
| 134 | + |
| 135 | +if refresh_response.success: |
| 136 | + access_token = refresh_response.data["access_token"] |
| 137 | +``` |
| 138 | + |
| 139 | +### Fetching App Installation Details |
| 140 | + |
| 141 | +In both user-authorized and app-authorized flows, the `app_installation_id` identifies the app's installation within a specific workspace. It is recommended that developers fetch workspace details after OAuth is successfully completed. Plane.so provides an `app-installation` endpoint that works with both types of tokens. |
| 142 | + |
| 143 | +#### Example Pseudo-code |
| 144 | + |
| 145 | +```python |
| 146 | +# Set authorization header with either access token or bot token |
| 147 | +headers = { |
| 148 | + "Authorization": f"Bearer {token}", |
| 149 | +} |
| 150 | + |
| 151 | +# Make GET request to fetch installation/workspace details |
| 152 | +response = GET( |
| 153 | + url=f"https://api.plane.so/auth/o/app-installation/?id={app_installation_id}", |
| 154 | + headers=headers |
| 155 | +) |
| 156 | + |
| 157 | +workspace_details = response.data |
| 158 | +``` |
| 159 | + |
| 160 | +## Using Plane SDKs |
| 161 | + |
| 162 | +To simplify the OAuth flow and make it easier to build Plane apps, official SDKs are available: |
| 163 | + |
| 164 | +* **Node.js**: `npm i @makeplane/plane-node-sdk` |
| 165 | +* **Python**: `pip install plane-sdk` |
| 166 | + |
| 167 | +These SDKs provide helpers for OAuth and other common tasks, allowing developers to implement the above flows efficiently. |
| 168 | + |
| 169 | +## Listing Your App on Plane Marketplace |
| 170 | + |
| 171 | +Apps built using the OAuth flow can be listed on the Plane Marketplace: [https://plane.so/marketplace/integrations](https://plane.so/marketplace/integrations) |
| 172 | + |
| 173 | +To list your app, please contact the Plane team at [**[email protected]**](mailto:[email protected]). |
0 commit comments