Which API documentation tool does a small SaaS need? For most, a free open-source renderer such as Swagger UI, Redoc or Scalar pointed at one OpenAPI file in the repository, with no hosted platform until outside developers depend on the docs. The tool is the small decision. The file, and whether it matches what the API returns, is the work.
Choosing an API documentation tool: what is being compared, and for whom
An API documentation tool turns a machine-readable description of an API, usually an OpenAPI file, into pages people can read and try. The options fall into 3 families: open-source renderers you host, docs built into a framework or platform, and hosted documentation platforms. Who reads the docs decides which family fits.
API documentation tools all start from that same job and differ in what they add on top, from nothing at all to hosting, versions and search. For a small SaaS with one API and one to three kinds of reader, the reader matters more than the feature list. The reference is also one piece of what a developer handoff looks like, next to the README and the runbooks, so the same file ends up serving the next engineer, a partner and a reviewer.
The description format that matters is OpenAPI. The OpenAPI Specification is at version 3.2.1, dated 10 September 2026, and the OpenAPI Initiative publishes it; it describes HTTP APIs so that “both humans and computers” can understand a service “without requiring access to source code”. Swagger is the format’s older name, and SmartBear’s own page still writes “OpenAPI (formerly known as Swagger) Specification”, while Swagger today is also the name of SmartBear’s tool family.
| Who reads your API docs | What they need from them | The smallest thing that serves them |
|---|---|---|
| Your own front end and the next engineer | Every route, its auth rule and its errors, correct on the day they read it | A rendered OpenAPI file in the repository or at an internal URL |
| A mobile or partner developer | The same, plus how to get a credential and a real example per call | The same rendered file, published, with auth instructions and examples |
| An acquirer’s or customer’s reviewer | A reference they can read offline, next to the other handover documents | A static HTML export in the handover pack |
| Paying outside developers at scale | Guides, search, versions and a changelog around the reference | A hosted documentation platform |
An app whose only API is the data layer its builder generated still has an API, and still has docs for it: the reference the data platform generates from the schema, which is one of the rows in the comparison below.
The comparison: eight options in one table
API documentation options for a small SaaS come down to 8, in three families. The open-source renderers and framework built-ins cost nothing, and the renderers can run as static files. Hosted platforms start free, charge monthly above that, and add guides, search, versioning and analytics. The deciding criteria are license, hosting, input format, a try-it console and entry price.
No option wins across the three families, so the table runs from the smallest setup to the largest. Choosing among the best API documentation tools starts with who reads the docs, and a small team rarely needs the rows at the bottom. “Try-it console” means a reader can send a real request from the docs page.
| Option | Family | License | Where it runs | Input it needs | Try-it console | Entry price | Best fit |
|---|---|---|---|---|---|---|---|
| Swagger UI | Open-source renderer | Apache 2.0 | Static files you host (the release’s /dist folder) | OpenAPI 3.x or Swagger 2.0 file | Yes, every operation | No license fee | Developer readers who want to send test calls |
| Redoc, built with Redocly CLI | Open-source renderer | MIT | One standalone HTML file you host | OpenAPI 3.1, 3.0 or Swagger 2.0 file | Not in open-source Redoc; Redocly’s hosted Redoc lists one | No license fee | A read-only reference for a handover pack |
| Scalar | Open-source renderer | MIT | A single HTML file loading Scalar’s build, a framework integration, or Scalar’s hosting | OpenAPI or Swagger document | Yes, built-in API client | Hosted Free plan $0 (up to 3 APIs, 1 editor seat); Pro $150/month | A reference with a test client built in |
| Framework built-in: FastAPI | Built into the framework | MIT (FastAPI) | Your own app, at /docs and /redoc | The code’s type hints | Yes, “Try it out” at /docs | No license fee | A Python API already on FastAPI |
| Data platform reference: Supabase | Built into the platform | Apache 2 (Supabase Studio, the Dashboard) | The Supabase Dashboard: Project Settings, then Data API, then Docs | The database schema | Not stated in Supabase’s docs | Part of the project; Supabase Free plan $0/month | The app’s own front end on a Supabase backend |
| Postman published docs | Built into the platform | Not stated in Postman’s docs | Postman’s hosting; private by default, public when published | A Postman Collection (an OpenAPI file is converted into one) | Through a “Run in Postman” button that forks the collection into the reader’s workspace | Free $0/month, 1 user, Postman-branded docs; Solo $9/month billed annually | A team that already keeps its requests in a collection |
| Docs-as-code platform: Mintlify | Hosted platform | Not stated in Mintlify’s docs | Mintlify’s hosting; self-hosting listed for Enterprise only | OpenAPI 3.0 or 3.1 file, from the docs repository or a URL | Yes, API playground | Starter $0/month; Pro $450/month with annual billing | Public docs with guides, written in the repository |
| General documentation hosts: GitBook; ReadMe | Hosted platform | Not stated in GitBook’s or ReadMe’s docs | GitBook’s hosting; ReadMe’s hosting | GitBook: Swagger 2.0, OpenAPI 3.0 or 3.1, as a file or URL. ReadMe: OpenAPI 3.0.x or 3.1, Swagger 2.0, Postman Collections | GitBook: API playground on every plan. ReadMe: authenticated requests from the reference | GitBook: Free $0 per site/month; Premium $65 per site/month billed annually, plus $12 per user/month. ReadMe: Starter $0/month; Pro $250/month billed annually | Docs as a product surface, with guides and non-developer editors |
Prices and features checked on 2026-10-04 against each vendor’s own docs, repository or pricing page; “Family” and “Best fit” are my own classification, not the vendors’.
When to pick each
The open-source renderers and the hosted and built-in options each get three answers below: when they fit, when they do not, and the one thing that rules them out. Redocly CLI sits between them because it lints, bundles and builds the OpenAPI file itself.
Open source API documentation tools: Swagger UI, Redoc and Scalar
Open-source API documentation tools worth shortlisting are Swagger UI, Redoc and Scalar. Each renders an OpenAPI file in the browser, has no license fee and can run as static files you host. They differ in try-it console and layout, and some extras sit in hosted products: Redoc’s try-it console in hosted Redoc, Scalar’s access groups in its Pro plan.
Swagger UI is SmartBear’s project, under the Apache 2.0 license. Its pitch is interaction: readers can “try out every single operation your API exposes”, and serving it needs no build step, since the repository says to copy the release’s /dist folder to your server.
Redoc is the MIT-licensed community edition from Redocly. It renders a three-panel page: search and navigation on the left, the documentation in the middle, request and response examples on the right. The open-source page is read-only; Redocly lists a “Try-it console” among the extras of its hosted Redoc.
Scalar is the newer project, MIT-licensed, from the company that runs scalar.com. It ships with an API testing tool, can run from a single HTML file, and lists integrations for FastAPI, NestJS, Express, Django and many more. Its hosted plans start with a Free tier, and what the paid ones add (custom domains, Git sync and access groups all start on Pro) is on Scalar’s pricing page.
An open source API documentation generator can mean two different tools. One is a renderer like these three, which turns the OpenAPI file into pages. The other produces the OpenAPI file itself from code or from a schema library such as Zod, which is the step before rendering and is covered in the template section below.
Fits when: you have one API, an OpenAPI file, and readers who are developers. Does not fit when: you need guides, search across many pages, access control on the docs, or analytics. The disqualifier: a reader who must not see the reference, because a static page has no login of its own unless your hosting adds one.
Redocly CLI: lint, bundle and build a static reference from the command line
Redocly CLI is an open-source command-line tool for OpenAPI files. A small team uses 3 of its commands: lint to check the file against rules, bundle to merge a multi-file spec, and build-docs to produce a single self-contained HTML reference that can ship in a handover pack.
# check the file against the default "recommended" ruleset
npx @redocly/cli@latest lint openapi.yaml
# merge a multi-file description into one file
npx @redocly/cli@latest bundle openapi.yaml -o dist/openapi.yaml
# build one standalone HTML reference (default name: redoc-static.html)
npx @redocly/cli@latest build-docs dist/openapi.yaml -o dist/api-reference.html
Redocly CLI comes from the company behind Redoc. Redocly CLI’s documentation gives three install routes: npm i @redocly/cli@latest in the project, npx at run time, or the redocly/cli Docker image. Version 2 runs on Node.js v22.12.0 or higher, or v20.19.0 or higher. The config file is redocly.yaml, and lint uses the recommended ruleset when no config says otherwise.
The free and paid line, in Redocly’s words: the CLI is “an open source command-line tool”, and Redocly “offers a full suite of API lifecycle tools as commercial offerings”. One limit to know before you choose a spec version: build-docs “currently supports only Swagger 2.0 and OpenAPI 3.0/3.1 descriptions”, with OpenAPI 3.2 support “coming soon”.
Two of these commands matter beyond the reference. lint in CI is half of the drift check further down, and the HTML file from build-docs is the thing that goes in a handover pack, since Redocly describes it as a standalone file that “can be easily shared or hosted on a platform of your choice”.
Spectral, from SmartBear’s Stoplight, is the alternative linter: a JSON and YAML linter with built-in OpenAPI support (v3.1, v3.0 and v2.0), Apache 2.0 licensed. It does the same job with a different ruleset format, so pick one linter, not both.
Hosted platforms, framework built-ins and Postman: when each earns its place
Hosted API documentation platforms earn a fee when docs are a product surface that needs guides, search, versions and analytics. Before that, free sources usually exist already: the framework’s built-in docs, as FastAPI serves from its type hints, and the data platform’s generated reference. A static file serves one reference page.
Framework built-ins come first because they are already running. FastAPI serves Swagger UI at /docs and ReDoc at /redoc, both built from the code’s type hints, and FastAPI’s docs URLs settings show how to move either one with docs_url or redoc_url, or turn it off by setting it to None. NestJS has a dedicated module, @nestjs/swagger, that generates the spec from decorators, and drf-spectacular does the same for Django REST framework.
An app built on Supabase already has the data platform’s reference, whether or not anyone has opened it. Supabase generates documentation for its Data API from the database schema and shows it in the Dashboard, updating as the schema changes, as Supabase’s API docs describe. Supabase’s docs also warn that tables and views exposed through that API without row level security “can be accessed by any role with matching grants”, so the generated reference doubles as a list of what to test in an API security assessment.
Postman suits teams whose saved requests already live in a collection and who want a shareable page without new tooling. Postman creates the documentation from the collection, keeps the published page in sync with it, and keeps it private until you publish or share it, per Postman’s guide to documenting an API. The limit is the source: the page tracks the collection, and nothing in that sync compares the collection with what the server returns.
Hosted platforms fit when the docs are part of the product: guides around the reference, versions, full-text search, a custom domain, analytics and AI search where the plan lists it. Their entry prices are in the comparison table, read on 2026-10-04 from Mintlify’s pricing, GitBook’s pricing and ReadMe’s pricing. The free plans are worth reading line by line: Mintlify’s Starter leaves out platform analytics, GitBook’s custom domain and search analytics start on Premium, with page view analytics on every plan, and ReadMe’s Starter keeps one published version, with private docs starting on Pro.
The disqualifier for a small app: a monthly fee to host one reference page that a static file would serve. The tie-breaker when you do buy: the platform has to take your OpenAPI file on every deploy, from the repository or a URL, so the file stays the source and the platform stays a renderer.
An API documentation template you can copy
An API documentation template for one endpoint has 10 fields: method and path, purpose, who may call it, parameters, request example, success response, every error and what to do about it, side effects, idempotency and retries, and a changelog line. Six one-time sections cover the basics once: purpose, URLs, authentication, conventions, errors and limits.
ONE-TIME SECTIONS (write once, link from every endpoint)
1. What the API is for: two sentences.
2. Base URLs: one per environment (production, staging).
3. Authentication: how to get a credential, where it goes, how it expires.
4. Conventions: id format, pagination, dates in UTC, money in minor units, idempotency keys.
5. Errors: the error body format, and every code the API returns.
6. Rate limits and versioning: the limits, and how a breaking change is announced.
PER ENDPOINT (copy once for each endpoint)
1. Method and path:
2. Purpose (one sentence):
3. Who may call it (role or scope):
4. Path and query parameters (type, required or not, limits):
5. Request body, with a real example:
6. Success response, with a real example:
7. Every error this endpoint returns, and what the caller should do:
8. Side effects (emails sent, webhooks fired, charges made):
9. Idempotency and retry behavior:
10. Changelog line (date, what changed):
Write it once, in OpenAPI, and the renderer prints it. The fields map onto an OpenAPI operation like this: purpose is summary and description, who may call it is security, parameters are parameters, the request body is requestBody, success and errors are responses, and the real examples go in examples. Side effects, retries and the changelog line go in description as plain sentences, and a webhook the call sends can also be described in the operation’s callbacks field, which the specification defines for requests “initiated by the API provider”.
For an app with no spec yet, there are three routes to a first file, cheapest first. Generate it from what the code already uses: the framework, as FastAPI and NestJS do, or the schema library, as zod-to-openapi does for Zod schemas under the MIT license. Have an AI assistant draft it from the route handlers, then correct the draft against real responses, field by field; an unread AI draft documents what the model expected, not what the server sends. Or write it yourself in the Swagger Editor, which validates the syntax “for OAS-compliance as you write it”.
There is no download here: the block above is the template. Where the API reference sits among the README, runbooks and decision notes is part of how to write technical documentation for a vibe-coded app.
An API documentation example: one endpoint, documented end to end
A complete API documentation example shows one endpoint with a real request, a real response and every error a caller must handle. The parts generated docs miss are who may call it, the side effects such as emails and webhooks, and what a retry with the same idempotency key returns.
The assumptions: a small invoicing SaaS with a REST API, bearer-token auth, and one endpoint that creates an invoice and emails it to the customer. I constructed the example for this page; it is not taken from a client’s app.
| Field | Filled in |
|---|---|
| Method and path | POST /v1/invoices |
| Purpose | Creates an invoice for a customer in your workspace and emails it to them. |
| Who may call it | An admin of the same workspace, with a bearer token. |
| Parameters | Header Idempotency-Key, required, string, up to 64 characters. No path or query parameters. |
| Request body | customer_id, currency, and lines (at least one line, each with description and amount in minor units). Example: {"customer_id": "cus_123", "currency": "usd", "lines": [{"description": "Setup", "amount": 50000}]} |
| Success response | 201 with the new invoice, for example {"id": "inv_456", "status": "sent", "total": 50000, "currency": "usd"} |
| Errors | 422: validation failed; fix the fields the error body names, then resend. 404: the customer does not exist in your workspace, which is also what a customer in another workspace returns; check the id, do not retry. 409: this Idempotency-Key was already used with a different body; send a new key for a new invoice. 401 and 403 come from the one-time authentication section. |
| Side effects | Emails the invoice to the customer and sends the invoice.created webhook to the workspace’s webhook URL. |
| Idempotency and retries | A retry with the same key and the same body returns the first 201 response and sends no second email. |
| Changelog | One dated line per change; the first reads “endpoint added”. |
The 404 for another workspace’s customer is deliberate: a 403 would confirm that the id exists somewhere. The same endpoint in OpenAPI, under 40 lines, with one request example and two response examples:
openapi: 3.1.1
info: { title: Invoicing API, version: 1.0.0, license: { name: Proprietary, identifier: LicenseRef-Proprietary } }
servers: [{ url: https://api.invoicing.internal }]
security: [{ bearerAuth: [] }]
paths:
/v1/invoices:
post:
operationId: createInvoice
summary: Create an invoice and email it to the customer
description: Workspace admins only. Emails the customer and sends the invoice.created webhook.
parameters:
- { name: Idempotency-Key, in: header, required: true, schema: { type: string, maxLength: 64 } }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/NewInvoice' }
examples:
basic: { value: { customer_id: cus_123, currency: usd, lines: [{ description: Setup, amount: 50000 }] } }
responses:
'201':
description: Created. A retry with the same key and body returns this same response.
content:
application/json:
examples: { created: { value: { id: inv_456, status: sent, total: 50000, currency: usd } } }
'404': { description: The customer does not exist in your workspace. }
'409':
description: The Idempotency-Key was already used with a different body.
content: { application/json: { examples: { reused_key: { value: { error: { code: idempotency_key_reused } } } } } }
'422': { description: Validation failed. The error body names each invalid field. }
components:
securitySchemes: { bearerAuth: { type: http, scheme: bearer } }
schemas:
NewInvoice:
type: object
required: [customer_id, currency, lines]
properties: { customer_id: { type: string }, currency: { type: string }, lines: { type: array, minItems: 1, items: { $ref: '#/components/schemas/Line' } } }
Line: { type: object, required: [description, amount], properties: { description: { type: string }, amount: { type: integer, description: Minor units } } }
The fragment declares 3.1.1 rather than the current 3.2.1 because build-docs reads only OpenAPI 3.0 and 3.1 for now, and Mintlify’s and ReadMe’s imports list 3.0 and 3.1 as well; tooling that supports 3.1 is meant to handle every 3.1.x patch. It passes redocly lint with the default ruleset.
Rendered by Redoc, the fragment becomes one page in the three-panel layout: the operation’s name and summary in the left menu with a search bar above it, the description, the Idempotency-Key header, the body schema and each response code in the middle, and the request example with the two response examples on the right. A reader learns who may call it, what happens on a retry and what each error means without opening the code. Given the same file, Swagger UI renders the Swagger version of this example instead, where a reader can try out the operation from the page.
What this example copies from Stripe’s API reference is the per-endpoint shape. Stripe’s Create an invoice entry prints the method and path, a one-line purpose, every parameter with its type, what the call returns, an example request and an example response, and a separate errors page lists each HTTP status with its meaning, including a 409 for a request that “conflicts with another request (perhaps due to using the same idempotent key)”.
The reference says what the endpoint does, not where it sits among the app’s services. That belongs on a diagram, and how to create architecture diagrams is the other half of what a reviewer reads.
How to verify the docs are true
API docs are verified with 5 checks: the OpenAPI file lints clean in CI, each documented example matches the real staging response, type or contract checks catch a deliberate contract mismatch before merge, the server’s route list matches the documented paths, and a newcomer reaches a first authenticated call without asking a question.
- 01 Lint the OpenAPI file in CI on every pull request, with zero errors. Fail: there is no file, or no lint step runs. Evidence: the CI log.
- 02 For every documented endpoint, send the documented example request to staging and compare the real response with the documented one, field by field: names and types, since ids and timestamps will differ. Fail: a field missing, renamed or of another type. Evidence: the diff.
- 03 Rename a response field in a branch and confirm a check fails before merge, either a contract test or a type error in a client generated from the file. Fail: the branch merges green. Evidence: the failing CI run. On the Production Hardening Sprint, deliverable 10.3, Typed API boundaries, is verified this way: introduce a deliberate contract mismatch and confirm type or contract checks catch it.
- 04 List the routes the server actually exposes, from the framework's own route listing, and diff them against the documented paths. Fail: a route the docs do not list; each one gets documented, secured or deleted. Evidence: the diff.
- 05 Hand the docs to someone who has not seen the code and time them to a first successful authenticated call. Fail: they need to ask you something; write the answer into the docs. Evidence: the time, and the questions they asked.
Check 3 can only fail if types or a contract test sit between the two sides, the same setup that keeps the case of when the frontend broke after a backend change from happening twice.
Picture a mobile developer building against the published API reference. A backend change renames a response field, the reference written once still shows the old name, nothing in CI compares the two, and the mobile release breaks on the field the docs promised. Docs stay true only while a check fails when the contract changes, so rename a field in a branch and watch the build fail before a partner finds it.
Where the sprint fits
No deliverable of the Production Hardening Sprint is called API documentation; four sit next to it. We define types at every API boundary and share contracts between frontend and backend using the stack’s appropriate tooling (10.3, the deliverable named in check 3 above). We organize the codebase consistently and explain its layout in the README, and deliverable 10.4, Documented repository structure, is verified this way: follow the README from a clean checkout and trace a core feature through its documented modules. For 13.3, Operating runbooks, we document deployment, rollback, key rotation, backup restoration and the response to each operational alert. We bundle the readiness report, architecture diagram, data model, security checklist and capacity statement into one PDF, the technical due diligence pack (13.6). New features and completing unfinished core workflows are separate work. Hosting, paid tools, and API usage remain in your accounts. Every deliverable and its verify step is on the published scope.
Common questions about documenting an API
What are the top 5 API management tools?
API management tools are a different product from an API documentation tool, and a small SaaS documenting one API does not need one, so I won’t rank five. In Microsoft Learn’s API Management key concepts, Azure API Management “is made up of an API gateway, a management plane, and a developer portal”, and the gateway verifies API keys and other credentials and enforces usage quotas and rate limits. For the docs alone, a renderer over the OpenAPI file is enough.
Who has the best API docs?
Stripe’s API reference is the model I’d copy, and the reasons are copyable: each endpoint shows its parameters with types, an example request and an example response, and the status codes the API returns are explained together on a single errors page. The worked example above follows that shape for a single invoice endpoint.
How do I use ReDoc in FastAPI?
You already have it: FastAPI serves ReDoc at /redoc by default, next to Swagger UI at /docs, both generated from the app’s OpenAPI schema. To move it, pass redoc_url with a new path when you create the FastAPI app; to turn it off, set redoc_url=None.
Is REST API obsolete?
No. OpenAPI describes HTTP APIs, and every renderer and hosted platform in this article reads an OpenAPI file, so a REST API documented in one file is still the ordinary case for a small SaaS. Some tools also read other styles, such as Redoc 3, which Redocly says adds GraphQL support, so choose by what your consumers call rather than by what is newest.
Owning an app means being able to run it, change it and recover it without guessing. The sprint below leaves you with the runbooks and documentation to do that.
Built it with AI. Now it has to hold up for real customers.
The Production Hardening Sprint takes the app you already have and builds the production foundation underneath it. Authentication and access rules, payments that stay consistent, error handling, monitoring, backups, automated tests and a documented handover. Our engineers work inside your existing codebase for ten working days. All 123 deliverables are included, and you get the evidence for each one.
See the Production Hardening Sprint →
$2,500 fixed price · 10 working days · One codebase