Skip to content

[feature]: Expose an openapi definition of the APIΒ #8636

@BryanDollery

Description

@BryanDollery

Is there an existing issue for this?

  • I have searched the existing issues

Summary

I might have gotten this wrong, but I can't find a way to get the openapi definition of the api from the api itself, or from the website. If this is available somewhere, please close this with a comment explaining it to me. I asked my AI assistant to help me write a bug-report/feature-request, so the rest of this is a bit wordy, sorry, but it has all the info you need on what I had to do to find the openapi spec and the problems with the spec once it was found...

OpenAPI / Swagger schema generation is broken and incomplete

Summary

drf-spectacular 0.28.0 is installed as a dependency but is not properly configured, making it impossible to generate a usable OpenAPI schema for the Plane API. The built-in DRF generateschema command also fails. With manual workarounds, a schema can be extracted, but it only covers 30 of what appears to be hundreds of endpoints, and the output is largely unusable.

Environment

  • Plane version: stable (Community Edition, Docker Compose deployment)
  • Python: 3.12
  • Django REST Framework: (bundled version)
  • drf-spectacular: 0.28.0 (installed but not configured)

I'm running the system locally using docker-compose directly from the git repo. I have exposed the api server port 8000 to the host for querying.

OpenAPI / Swagger schema generation is broken and incomplete

Summary

drf-spectacular 0.28.0 is installed as a dependency but is not properly configured, making it impossible to generate a usable OpenAPI schema for the Plane API. The built-in DRF generateschema command also fails. With manual workarounds, a schema can be extracted, but it only covers 30 of what appears to be hundreds of endpoints, and the output is largely unusable.

Environment

  • Plane version: stable (Community Edition, Docker Compose deployment)
  • Python: 3.12
  • Django REST Framework: (bundled version)
  • drf-spectacular: 0.28.0 (installed but not configured)

What I tried

1. No schema endpoint is exposed

None of the standard OpenAPI/Swagger endpoints return anything:

/swagger.json          β†’ 404
/openapi.json          β†’ 404
/api/schema/           β†’ 404
/api/v1/schema/        β†’ 404
/api/swagger/          β†’ 404
/api/docs/             β†’ 404
/api/redoc/            β†’ 404

There is no way for API consumers to discover the schema at runtime.

2. manage.py generateschema crashes

docker compose exec api python manage.py generateschema --format openapi-json

Fails with:

AssertionError: 'CycleFavoriteViewSet' should either include a `serializer_class`
attribute, or override the `get_serializer_class()` method.

Multiple views are missing serializer_class, which causes DRF's built-in schema generator to crash.

3. manage.py spectacular is not registered

docker compose exec api python manage.py spectacular
# Unknown command: 'spectacular'

Despite drf-spectacular being installed, it is not in INSTALLED_APPS, so its management command is unavailable.

4. Workaround that partially works

The only way to extract a schema is to invoke drf-spectacular's SchemaGenerator directly in Python, after patching DEFAULT_SCHEMA_CLASS at runtime:

docker compose exec api python -c "
import os, json, sys
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'plane.settings.production')
import django; django.setup()
from django.conf import settings
settings.REST_FRAMEWORK['DEFAULT_SCHEMA_CLASS'] = 'drf_spectacular.openapi.AutoSchema'
from drf_spectacular.generators import SchemaGenerator
generator = SchemaGenerator()
schema = generator.get_schema()
sys.stdout.write(json.dumps(schema, indent=2, default=str))
"

This produces a schema, but with severe gaps (see below).

What is wrong with the generated schema

Only 30 of hundreds of endpoints are included

The generated schema contains only 30 paths. These are mostly:

  • /api/public/anchor/{anchor}/* β€” public embed/share endpoints
  • /auth/* β€” authentication flows (email-check, forgot-password, magic-generate, csrf)
  • /api/instances/ β€” instance metadata
  • /api/users/session/ β€” session check
  • A couple of workspace/project join endpoints

Entirely missing (non-exhaustive):

Domain Example routes
Workspaces /api/v1/workspaces/, CRUD, members, invitations
Projects /api/v1/workspaces/{slug}/projects/, settings, members
Issues /api/v1/workspaces/{slug}/projects/{id}/issues/, bulk ops
Cycles /api/v1/workspaces/{slug}/projects/{id}/cycles/
Modules /api/v1/workspaces/{slug}/projects/{id}/modules/
Views / Filters Saved views, filter endpoints
Labels /api/v1/workspaces/{slug}/projects/{id}/labels/
States /api/v1/workspaces/{slug}/projects/{id}/states/
Pages /api/v1/workspaces/{slug}/projects/{id}/pages/
Analytics All analytics endpoints
Notifications User notification endpoints
Integrations GitHub, Slack, etc.
Webhooks /api/v1/workspaces/{slug}/webhooks/
API tokens /api/v1/workspaces/{slug}/api-tokens/

Almost all responses are undocumented

28 of 30 endpoints return "description": "No response body" with no response schema. Only IssueComment list/detail have actual response schemas.

Metadata is empty

"info": {
  "title": "",
  "version": "0.0.0"
}

Descriptions are generic

Nearly every endpoint has the same description inherited from a mixin:

"This enables timezone conversion according to the user set timezone"

Security schemes are incomplete

Only cookieAuth (session cookie) is documented. The API key authentication (X-Api-Key header) used by /api/v1/ endpoints is not declared.

Suggested fixes

  1. Add drf_spectacular to INSTALLED_APPS so manage.py spectacular works out of the box.

  2. Set DEFAULT_SCHEMA_CLASS in REST_FRAMEWORK settings:

    REST_FRAMEWORK = {
        ...
        'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
    }
  3. Configure SPECTACULAR_SETTINGS with proper metadata:

    SPECTACULAR_SETTINGS = {
        'TITLE': 'Plane API',
        'DESCRIPTION': 'Project management for product teams',
        'VERSION': '1.0.0',
        'SERVE_INCLUDE_SCHEMA': False,
    }
  4. Add serializer_class (or @extend_schema decorators) to views that are missing them (e.g., CycleFavoriteViewSet, analytics endpoints, and others flagged as "not compatible with schema generation").

  5. Expose a schema endpoint (e.g., /api/schema/) so API consumers and tools can discover the API at runtime.

  6. Document API key authentication in the security schemes for v1 API endpoints.

Impact

  • MCP / AI tool integration: Tools like the Plane MCP server cannot auto-discover available endpoints and must hard-code API calls.
  • Third-party integrations: Developers building on the Plane API have no machine-readable contract.
  • Client SDK generation: Without a complete schema, generating typed clients (TypeScript, Python, Go) is impossible.
  • API testing: Contract testing tools (Schemathesis, Dredd) cannot validate the API.

Why should this be worked on?

I've been asked by a large organisation to migrate from jira to plane (driven by the supply chain risk introduced by the Cloud Act - SaaS is dead, so we need our own task management system). I cannot do this manually - it's a bank. I need the API, I need to be able to create users too, and have one user (an admin) create tickets on behalf of another user. I need to have the openapi spec to even start. And, I'm not the only one.

I've read through the project docs, it appears that you're headed in this direction, but I need this to work, and I imagine a lot of people have the same problem. This type of tool is enterprise class, but without the ability to automate migrations it is effectively unusable.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions