Skip to content

Commit 31f11b4

Browse files
restructure build plane app documentation
- Revamp introduction and add new Why build Plane App section - Use concrete code examples
1 parent 91892fb commit 31f11b4

File tree

1 file changed

+75
-42
lines changed

1 file changed

+75
-42
lines changed

guides/build-plane-app.mdx

Lines changed: 75 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,62 @@
11
---
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.
2+
title: Build a Plane App (Beta)
3+
sidebarTitle: Build a Plane App (Beta)
4+
description: Step-by-step guide for developers to build and integrate an app with Plane using OAuth-based authentication and authorization workflow.
55
---
66

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.
7+
<Note>Plane apps are currently in **Beta**. Please send any feedback to support@plane.so.</Note>
88

99
## Introduction
10+
Plane apps (beta) seamlessly integrate tools and services with Plane so you can use them without ever leaving your Workspace. Apps are conveniently available from our [marketplace](https://plane.so/marketplace/integrations), helping you stay focused and productive.
1011

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+
## Why Build a Plane App?
13+
Plane has a large ecosystem of users, build community integrations to highlight your product or service to the Plane community, or simply build an integration for your own internal requirements.
14+
15+
Stop doing manual work. Plane integrations eliminate repetitive tasks like copying updates between tools, creating work items from support tickets, or generating status reports. Instead of spending hours on administrative work, let your integration handle it automatically.
16+
17+
Connect everything you already use. Your team probably uses 5-10 different tools. Plane integrations create a unified workflow by connecting your CRM, time tracking, CI/CD pipelines, communication tools, and more. One change in Plane can trigger updates across your entire tech stack.
18+
19+
Build exactly what you need. Unlike rigid SaaS platforms, Plane's open-source nature means you can create integrations that fit your specific workflow.
20+
21+
### Promote Your Plane Integration
22+
Contact us to help promote your Plane integration and feature it within blogs and Plane itself: [email protected]
1223

1324
## Prerequisites
1425

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.
26+
- A [Plane](https://app.plane.so) workspace
27+
- Admin access to your workspace settings
28+
- Familiarity with OAuth 2.0 concepts (authorization code flow).
29+
- A backend server to handle OAuth token exchange.
1930

2031
## High-Level Workflow
2132

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**
33+
1. [Register your app on Plane developer portal](/guides/build-plane-app/#registering-your-app)
34+
2. [Implement OAuth authorization code flow](/guides/build-plane-app#authentication-setup)
35+
3. Obtain and store access tokens securely
36+
4. Make authenticated API requests to Plane
37+
5. Handle token refresh
2738

2839
## Registering Your App
2940

30-
To build an OAuth application with Plane.so:
41+
To build an OAuth application with Plane:
3142

3243
1. Navigate to `https://app.plane.so/<workspace_slug>/settings/applications/`.
3344
2. Click on the **Build your own** button.
3445
3. Fill out the form with the required details:
3546

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.
47+
- **Redirect URIs**: Provide the URIs where Plane will send the authorization code.
48+
- **Contact Details**: Add your email or other contact information.
49+
- **Webhook URL Endpoint**: Update this with your service's webhook endpoint. Plane will send webhooks for all changes that happen in the installed workspace.
50+
- **Organization Details**: Include contact email, privacy policy URL, terms of service URL, and any other relevant information. This helps Plane validate and approve your application for listing in the marketplace.
51+
4052
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.
53+
5. Once the app is created, securely store the **Client ID** and **Client Secret**. You will need these credentials to interact with Plane's API during the OAuth flow and for making authenticated API requests.
4254

4355
## Authentication Setup
4456

4557
### Generating Consent URL
4658

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:
59+
Before handling authentication, if your app manages installation, you must generate the consent (authorization) URL to initiate the OAuth flow. Below is a sample Python implementation:
4860

4961
```python
5062
params = {
@@ -59,20 +71,25 @@ consent_url = f"https://api.plane.so/auth/o/authorize-app/?{urlencode(params)}"
5971

6072
There are two types of authenticated actions your application can perform:
6173

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).
74+
1. **User-authorized actions**: Actions performed on behalf of a user after they grant permission to your app via OAuth.
75+
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).
6476

6577
We will describe how to configure and use each type in the following sections.
6678

6779
### App-Authorized Actions (Client Credentials Flow)
6880

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.
81+
When the app is installed, Plane 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.
7082

71-
#### Example Pseudo-code
83+
#### Examples
7284

7385
```python
86+
import base64
87+
import requests
88+
7489
# Prepare basic auth header using client_id and client_secret
75-
basic_auth = base64encode("client_id:client_secret")
90+
client_id = "your_client_id"
91+
client_secret = "your_client_secret"
92+
basic_auth = base64.b64encode(f"{client_id}:{client_secret}".encode()).decode()
7693

7794
# Prepare request data
7895
payload = {
@@ -81,25 +98,34 @@ payload = {
8198
}
8299

83100
# Make a POST request to fetch bot token
84-
response = POST(
101+
response = requests.post(
85102
url="https://api.plane.so/auth/o/token/",
86103
headers={"Authorization": f"Basic {basic_auth}",
87104
"Content-Type": "application/x-www-form-urlencoded"},
88105
data=payload
89106
)
90107

91-
bot_token = response.data['access_token']
92-
expires_in = response.data["expires_in"]
108+
# Parse the response
109+
response_data = response.json()
110+
bot_token = response_data['access_token']
111+
expires_in = response_data["expires_in"]
93112
```
94113

95114
### User-Authorized Actions (Authorization Code Flow)
96115

97116
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.
98117

99-
#### Example Pseudo-code
118+
#### Examples
100119

101120
```python
121+
import requests
122+
102123
# Exchange authorization code for access and refresh tokens
124+
code = "authorization_code_from_callback"
125+
client_id = "your_client_id"
126+
client_secret = "your_client_secret"
127+
redirect_uri = "your_redirect_uri"
128+
103129
payload = {
104130
"grant_type": "authorization_code",
105131
"code": code,
@@ -108,15 +134,17 @@ payload = {
108134
"redirect_uri": redirect_uri
109135
}
110136

111-
response = POST(
137+
response = requests.post(
112138
url="https://api.plane.so/auth/o/token/",
113139
headers={"Content-Type": "application/x-www-form-urlencoded"},
114140
data=payload
115141
)
116142

117-
access_token = response.data["access_token"]
118-
refresh_token = response.data["refresh_token"]
119-
expires_in = response.data["expires_in"]
143+
# Parse the response
144+
response_data = response.json()
145+
access_token = response_data["access_token"]
146+
refresh_token = response_data["refresh_token"]
147+
expires_in = response_data["expires_in"]
120148

121149
# When access token expires, use refresh token to get a new access token
122150
refresh_payload = {
@@ -126,29 +154,33 @@ refresh_payload = {
126154
"client_secret": client_secret
127155
}
128156

129-
refresh_response = POST(
157+
refresh_response = requests.post(
130158
url="https://api.plane.so/auth/o/token/",
131159
headers={"Content-Type": "application/x-www-form-urlencoded"},
132160
data=refresh_payload
133161
)
134162

135-
access_token = refresh_response.data["access_token"]
163+
# Parse the refresh response
164+
refresh_response_data = refresh_response.json()
165+
access_token = refresh_response_data["access_token"]
136166
```
137167

138168
### Fetching App Installation Details
139169

140-
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.
170+
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 provides an `app-installation` endpoint that works with both types of tokens.
141171

142-
#### Example Pseudo-code
172+
#### Examples
143173

144174
```python
175+
import requests
176+
145177
# Set authorization header with either access token or bot token
146178
headers = {
147179
"Authorization": f"Bearer {token}",
148180
}
149181

150182
# Make GET request to fetch installation/workspace details
151-
response = GET(
183+
response = requests.get(
152184
url=f"https://api.plane.so/auth/o/app-installation/?id={app_installation_id}",
153185
headers=headers
154186
)
@@ -157,6 +189,7 @@ workspace_details = response.data[0]
157189
```
158190

159191
#### Sample Response
192+
160193
```
161194
[
162195
{
@@ -184,13 +217,13 @@ workspace_details = response.data[0]
184217

185218
To simplify the OAuth flow and make it easier to build Plane apps, official SDKs are available:
186219

187-
* **Node.js**: `npm i @makeplane/plane-node-sdk`
188-
* **Python**: `pip install plane-sdk`
220+
- **Node.js**: `npm i @makeplane/plane-node-sdk`
221+
- **Python**: `pip install plane-sdk`
189222

190223
These SDKs provide helpers for OAuth and other common tasks, allowing developers to implement the above flows efficiently.
191224

192225
## Listing Your App on Plane Marketplace
193226

194227
Apps built using the OAuth flow can be listed on the Plane Marketplace: [https://plane.so/marketplace/integrations](https://plane.so/marketplace/integrations)
195228

196-
To list your app, please contact the Plane team at [**[email protected]**](mailto:[email protected]).
229+
To list your app, please contact the Plane team at [**[email protected]**](mailto:[email protected]).

0 commit comments

Comments
 (0)