API Documentation (Part 1)#

This is the 17th article in the Django Ninja series. We are starting Chapter 4 — API Documentation.
"Automatically generating API documentation based on code" is a major selling point of Django Ninja.
In fact, the automation of API documentation was the primary consideration for transitioning my work projects from Django REST framework to Django Ninja—and it was also the trigger for me to start learning Django Ninja.
Django Ninja saves a massive amount of time spent manually writing (we used to use API Blueprint) API documentation. Especially when API specifications change, there is no need to manually synchronize documentation changes, which greatly reduces the effort required to maintain documents.
It's clear how important this feature is.
Considerations on Teaching Order#
So, why did I wait until the 17th article of the series—this article—to start introducing Django Ninja's API documentation features?
The reason is that to generate excellent API documentation, you need to have a certain understanding of how Schemas are used. Therefore, I had to place this after Chapter 3.
Now, we are going to explore how to use Django Ninja to produce high-quality API documentation.
For all code changes in this article, you can refer to this PR.
GitHub Example Project#
Documentation as Code#
In modern software development, "Documentation as Code" (DoC) is an increasingly recognized concept.
DoC means tightly combining documentation with code, where developers use "the same processes and tools used for software code development" to create and maintain documentation.
Documentation is automatically updated as the code changes, keeping the two in sync at all times.
This not only improves development efficiency but also reduces miscommunication or misunderstanding caused by outdated documentation.
Django Ninja's automated documentation generation feature is undoubtedly a practice of the "Documentation as Code" spirit.
We can automatically generate OpenAPI-compliant documentation by writing code such as API routes, view functions, and Schemas. When the code changes, these documents will also automatically reflect the changes, with no manual maintenance required.
Two Key Aspects of Django Ninja's Automated API Documentation#
In Django Ninja, generating high-quality API documentation mainly involves two key aspects:
- Django Ninja Settings: Django Ninja has built-in settings to control API documentation details, which is the focus of this article.
- Pydantic Settings: This is the focus of the next article, covering how to effectively define Schemas so that various details are automatically presented in the API documentation.
Seeing this, are you a little excited? ☺️
Current Status of Project API Documentation#
Before we start aggressively improving the documentation quality, let's take a look at how "barebones" the current API documentation is.
After starting the Django server, you can view the current API documentation by visiting the following URL:
The current document content is as follows:

Let's briefly analyze this from the perspective of "whether it is useful and readable for developers."
Problems#
First, it has no grouping!
The APIs for the Django user app and post app are all mixed together. As the number of APIs grows, it will look extremely cluttered. This is the highest priority issue to solve.
Secondly, the API descriptions such as "Get Users" and "Create Post" are obviously auto-converted from the view function names. The information is limited, not colloquial enough, and not detailed enough—simply put, it is not sufficiently "reader-friendly."
Let's click into the only POST API to see its content:

The detail page says "Create Post," a description taken from the view function's docstring:
Let's also look at the HTTP request body example:
It can only be described as less than ideal. An example like "string" only shows the "type" and does not simulate a real-world post title or content.
The above issues are precisely the key areas we need to improve in our API documentation.
Among them, the request body example is related to the Schema configuration, which is the focus of the next article.
This article focuses first on Django Ninja settings—let's introduce them one by one.
1. Using Tags to Group APIs#
The first issue we need to solve is the grouping (categorization) of APIs.
To make the documentation structure clearer, Django Ninja supports using Tags to group APIs. This not only helps organize the documentation but also allows developers or users to find the APIs they need faster.
Tags grouping can be configured in two places.
Root-Level Routing Grouping#
The most common approach is to configure it at the root-level routing:
# NinjaForum/api.py
api.add_router(prefix='', router='user.api.router', tags=['User'])
api.add_router(prefix='', router='post.api.router', tags=['Post'])
This is because APIs within the same Django app usually belong in the same group.
Route Decorator Grouping#
You can also configure grouping in the route decorator, but I believe this is a relatively "exceptional" case, primarily used when:
- The entire project has only one Django app.
- The same Django app requires different groups.
For example, in the following example, there is no separation of Django apps, but there is still a need for grouping:
from ninja import NinjaAPI
api = NinjaAPI()
@api.get("/users/", tags=["User"])
def get_users(request):
...
@api.post("/posts/", tags=["Post"])
def create_post(request, title: str):
...
For most cases, I recommend grouping at the root-level routing.
Otherwise, tagging them one by one like in the example above is a bit tedious to implement.
2. Documentation Settings for Route Decorators#
Django Ninja's route decorators not only configure the basic API paths but also allow you to add description text for the API, which will be directly reflected in the generated API documentation.
Through these settings, you can add descriptions for API parameters, responses, and even intentions, making the documentation more comprehensive.
You can provide descriptions for each API route using the description and summary parameters. However, description will override the aforementioned "docstring to API description" behavior, so I usually only write summary.
After all, we write Python, and docstrings are a must!
The code is as follows:
@router.get(..., summary='Get Post List')
def get_posts(...) -> QuerySet[Post]:
"""
Get Post List
"""
...
Here is the result after adding grouping and API descriptions:

Very nice!
3. NinjaAPI Settings#
You can customize some global API documentation details through the initialization settings of the NinjaAPI class. For example:
# NinjaForum/api.py
from ninja import NinjaAPI
api = NinjaAPI(
title="Ninja Forum API",
version="1.0",
description="API documentation for the Ninja Forum example project."
)
Here is the result:

The initialization settings for NinjaAPI are very diverse—some of them might be what you need.
This is just a simple example. For more setting details, you can check the documentation.
Summary#
In this article, we explored common settings for automatically generating API documentation in Django Ninja, allowing the "Documentation as Code" spirit to be realized—code and documentation can easily remain consistent, reducing the hassle of manual maintenance.
However, the quality of API documentation also depends on how we define the details in the Schema.
Next, we will explore this topic in depth, explaining how to provide high-quality documentation examples through Pydantic's Field parameter settings to further improve the readability and clarity of API documentation.