How to Integrate Plane with Other Tools: A Complete Guide to Workspace Integrations
Plane integrates with external tools through a workspace-level model using the IWorkspaceIntegration interface, where services like IntegrationService and WebhookService manage CRUD operations and repository syncing via REST endpoints.
Plane is an open-source project management platform that connects with GitHub, Slack, Jira, and generic webhooks through a unified service-driven architecture. According to the makeplane/plane source code, every external connection is stored as a workspace-level configuration object, enabling teams to sync repositories, automate notifications, and import data from legacy systems.
Understanding Plane's Integration Architecture
Plane's integration layer separates concerns between the data model, service layer, and UI components. This architecture allows developers to extend the platform with new providers by following predictable patterns.
The IWorkspaceIntegration Data Model
Every external tool connection in Plane is represented by an IWorkspaceIntegration object defined in [packages/types/src/integration.ts](https://github.com/makeplane/plane/blob/preview/packages/types/src/integration.ts). This interface stores provider metadata, configuration secrets, and webhook endpoints at the workspace scope.
export interface IWorkspaceIntegration {
id: string;
provider: string; // e.g. "github", "slack"
integration_detail: {
title: string;
description: string;
logo_url: string;
provider: string; // matches `provider`
// …
};
webhook_url?: string; // for generic webhooks
webhook_secret?: string; // secret used by Plane to sign payloads
}
Workspace administrators manage these integrations through settings paths like /settings/webhooks or /settings/integrations, while the client application consumes them through dedicated service classes.
Integration Services in the Frontend
The frontend implementation resides in apps/web/core/services/ and extends a base APIService class that handles request building and error handling. Each service targets specific integration workflows.
IntegrationService for Workspace Management
The IntegrationService class in [apps/web/core/services/integrations/integration.service.ts](https://github.com/makeplane/plane/blob/preview/apps/web/core/services/integrations/integration.service.ts) handles CRUD operations for workspace-level integrations and manages importer/export services.
Key methods include:
getAppIntegrationsList()– Retrieves available integration providersgetWorkspaceIntegrationsList(workspaceSlug)– Lists active workspace connectionsdeleteWorkspaceIntegration(workspaceSlug, integrationId)– Removes an existing integrationgetImporterServicesList()andgetExportsServicesList()– Handles data migration tools
ProjectService for Repository Syncing
When syncing external repositories with Plane projects, the ProjectService in [apps/web/core/services/project/project.service.ts](https://github.com/makeplane/plane/blob/preview/apps/web/core/services/project/project.service.ts) provides provider-specific methods:
syncGithubRepository(workspaceSlug, projectId, integrationId, repo)– Links a GitHub repository to a Plane projectgetProjectGithubRepository(workspaceSlug, projectId)– Retrieves the currently synced repository
WebhookService for Generic Connections
For custom integrations, the WebhookService in [packages/services/src/developer/webhook.service.ts](https://github.com/makeplane/plane/blob/preview/packages/services/src/developer/webhook.service.ts) manages incoming and outgoing webhooks:
list(workspaceSlug)– Enumerates configured webhookscreate(workspaceSlug, payload)– Registers a new webhook endpointupdate(workspaceSlug, webhookId, payload)– Modifies existing webhook configurationdestroy(workspaceSlug, webhookId)– Deletes a webhookregenerateSecretKey(workspaceSlug, webhookId)– Rotates the HMAC secret used for payload signing
UI Implementation for Integrations
The frontend renders integrations through data-driven components that adapt to each provider's requirements.
The IntegrationCard Component
The IntegrationCard component in apps/web/core/components/project/integration-card.tsx displays integration metadata and provider-specific configuration widgets:
- GitHub integrations render a
SelectRepositorydropdown that callsProjectService.syncGithubRepositoryupon selection - Slack integrations display a
SelectChannelcomponent that stores the chosen channel via the Slack-specific service
The component uses SWR for data fetching and MobX for cache invalidation, ensuring the UI reflects real-time integration state changes.
Backend API Endpoints for Integrations
Plane's Django backend exposes REST endpoints that mirror the frontend service layer. All routes are scoped to workspace slugs and require appropriate authentication.
| Endpoint | Method | Description |
|---|---|---|
/api/workspaces/{workspaceSlug}/workspace-integrations/ |
GET |
List all integrations for a workspace |
/api/workspaces/{workspaceSlug}/workspace-integrations/{integrationId}/provider/ |
DELETE |
Remove an integration |
/api/workspaces/{workspaceSlug}/importers/ |
GET |
List importer services (e.g., Jira) |
/api/workspaces/{workspaceSlug}/projects/{projectId}/workspace-integrations/{integrationId}/github-repository-sync/ |
POST |
Sync a GitHub repo with a project |
/api/workspaces/{workspaceSlug}/webhooks/ |
GET, POST |
List or create generic webhooks |
/api/workspaces/{workspaceSlug}/webhooks/{webhookId}/regenerate/ |
POST |
Regenerate the secret key for a webhook |
Adding a New Integration to Plane
To integrate Plane with a new external tool (for example, Asana), follow this extension pattern:
-
Extend the type definitions in
packages/types/src/integration.tsif the new provider requires additional metadata fields beyond the standardIWorkspaceIntegrationinterface. -
Create a provider-specific service under
apps/web/core/services/integrations/(following the pattern ofgithub.service.ts) that implements API calls for listing projects, fetching users, or syncing data. -
Build UI components (such as
SelectProject) and conditionally render them inIntegrationCardby checkingintegration.integration_detail.provider === "asana". -
Implement backend routes in Django at
/api/workspaces/{workspaceSlug}/workspace-integrations/{id}/provider/to handle CRUD operations for the new provider.
Practical Code Examples
Listing All Workspace Integrations
import { IntegrationService } from "@/services/integrations/integration.service";
const integrationService = new IntegrationService();
async function loadIntegrations(workspaceSlug: string) {
const integrations = await integrationService.getWorkspaceIntegrationsList(workspaceSlug);
console.log("Integrations:", integrations);
}
Syncing a GitHub Repository
import { ProjectService } from "@/services/project";
const projectService = new ProjectService();
async function syncRepo(
workspaceSlug: string,
projectId: string,
integrationId: string,
repo: { name: string; owner: string; repository_id: string; url: string }
) {
await projectService.syncGithubRepository(
workspaceSlug,
projectId,
integrationId,
repo
);
console.log("Repository synced!");
}
Creating a Generic Webhook
import WebhookService from "@plane/services/webhook.service";
const webhookService = new WebhookService();
async function createWebhook(workspaceSlug: string) {
const webhook = await webhookService.create(workspaceSlug, {
url: "https://myapp.com/plane/webhook",
secret: "random-generated-secret",
});
console.log("Webhook created:", webhook.id);
}
Rendering Integration Cards in React
import { IntegrationCard } from "@/components/project/integration-card";
import type { IWorkspaceIntegration } from "@plane/types";
function IntegrationsList({ integrations }: { integrations: IWorkspaceIntegration[] }) {
return (
<div>
{integrations.map((intg) => (
<IntegrationCard key={intg.id} integration={intg} />
))}
</div>
);
}
Summary
- Plane uses a workspace-level integration model centered on the
IWorkspaceIntegrationinterface defined inpackages/types/src/integration.ts. - Frontend services like
IntegrationService,ProjectService, andWebhookServicehandle all API communication for managing connections and syncing data. - The backend exposes REST endpoints under
/api/workspaces/{workspaceSlug}/for CRUD operations on integrations, importers, and webhooks. - UI components such as
IntegrationCardadapt dynamically to provider types, enabling GitHub repository selection and Slack channel configuration. - Adding new providers requires extending type definitions, creating service classes, building UI components, and implementing Django routes.
Frequently Asked Questions
How does Plane secure webhook integrations?
Plane secures webhooks through HMAC signature validation using a webhook_secret stored in the IWorkspaceIntegration model. When creating a webhook via WebhookService.create(), you provide a secret key that Plane uses to sign payloads. You can rotate compromised secrets by calling regenerateSecretKey() without deleting the webhook configuration.
Can I integrate Plane with internal or self-hosted tools?
Yes. Plane's generic webhook system in packages/services/src/developer/webhook.service.ts supports any HTTP endpoint, making it compatible with self-hosted CI/CD pipelines, internal notification systems, or custom automation platforms. For deeper integrations, you can extend IWorkspaceIntegration and implement custom service classes following the existing GitHub/Slack patterns.
What is the difference between workspace integrations and project-level syncing?
Workspace integrations (managed by IntegrationService) establish the connection credentials and provider configuration at the workspace scope. Project-level syncing (handled by ProjectService methods like syncGithubRepository) associates specific external resources—such as individual GitHub repositories—with particular Plane projects within that workspace.
Which import and export services does Plane support?
According to the IntegrationService implementation in apps/web/core/services/integrations/integration.service.ts, Plane provides getImporterServicesList() and getExportsServicesList() methods that expose services like Jira importers. These endpoints allow teams to migrate existing project data into Plane or export Plane data for external analysis.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →