Editing the API docs

Last updated:

|Edit this page

The PostHog API docs are generated using drf-spectacular. It looks at the Django models and djangorestframework serializers.

Note: We don't automatically add new API endpoints to the sidebar. You need to add those to src/navs/index.js

You can add a help_text="Field that does x" attribute to any Model or Serializer field to help users understand what a specific field is used for:

Python
class Insight(models.Model):
last_refresh: models.DateTimeField = models.DateTimeField(blank=True, null=True, help_text="When the cache for the result of this insight was last refreshed.")
class InsightSerializer(TaggedItemSerializerMixin, InsightBasicSerializer):
filters_hash = serializers.CharField(
read_only=True,
help_text="A hash of the filters that generate this insight.",
)

To add a description to the top of a page, add a comment to the viewset class:

Python
class InsightViewSet(TaggedItemViewSetMixin, StructuredViewSetMixin, viewsets.ModelViewSet):
"""
Stores saved insights along with their entire configuration options. Saved insights can be stored as standalone
reports or part of a dashboard.
"""

To check what any changes will roughly look like locally, you can go to http://127.0.0.1:8000/api/schema/redoc/.

To add a description to a specific endpoint, add an MDX file (named after the endpoint ID's name) to the corresponding folder its page would belong to. Then, the content in the MDX file will only appear under the specified endpoint. This is like our MDX setup, except the file name will determine which endpoint the MDX contents appear on.

For example, to add a description to the "list annotations" endpoint, you'd create a new file: contents/docs/api/annotations/annotations_list.mdx

Whatever you add to that file will appear under that endpoint only.

API endpoint description

Insights serializer

The serializer for insight lives here. Each time an insight gets created we check it against these serializers, and we'll send an error to Sentry (but not the user) if it doesn't match, to ensure the API docs are up to date.

Documenting custom endpoints

If you have an @action endpoint or a custom endpoint (that doesn't use DRF) you can still document by providing a serializer for the request and response.

Python
from drf_spectacular.utils import OpenApiResponse
from posthog.api.documentation import extend_schema
@extend_schema(
request=FunnelSerializer,
responses=OpenApiResponse(
response=FunnelStepsResultsSerializer,
description="Note, if funnel_viz_type is set the response will be different.",
),
methods=["POST"],
tags=["funnel"],
operation_id="Funnels",
)
@action(methods=["GET", "POST"], detail=False)
def funnel(self, request: request.Request, *args: Any, **kwargs: Any) -> Response:

Testing API docs locally

To test or develop the API docs locally, you need to create a personal API key (see top of this page) and then export it before running gatsby, in the same terminal window:

Terminal
export POSTHOG_PERSONAL_API_KEY=yourkey

Questions?

Was this page useful?

Next article

Words & Pictures team overview

We couldn't think of a better name for this team, so we just called it Words & Pictures. We aim to delight users through our art, our copy, our ads, and anything else that somehow falls into our remit. That can include anything from onboarding emails, to designing our merch, to posting ads, to planning product launches. As a team we value being hands-on, putting human needs above internal processes, and sprinkling some chaos into everything we touch. Check out our team page for more info.

Read next article