---
title: "API Documentation"
guide-section: "Site Content"
bread-crumbs: false
tags: [API, Content]
---

# API Documentation

Most Python packages need an API reference, but writing one by hand is tedious and keeping it in
sync with code changes is even harder. Great Docs takes care of both: it automatically discovers
your package's public API through static analysis, classifies every export by type, and generates a
complete, styled reference section. You can ship a polished API reference without writing a single
docstring page yourself, and as your code evolves the documentation stays up to date.

This page explains how discovery works, what gets documented, and how to customize the result.

## How Discovery Works

When you run `great-docs init` or `great-docs build`, Great Docs:

1. **Finds your package**: looks in standard locations (`src/`, `python/`, project root)
2. **Uses static analysis**: analyzes your code with `griffe` without importing it
3. **Discovers public names**: finds all non-private names (not starting with `_`)
4. **Introspects submodules**: drills into exported modules to discover their classes, functions,
and constants
5. **Categorizes items**: classifies every export into one of 13 object types
6. **Generates configuration**: creates API reference sections in `_quarto.yml`

The entire pipeline runs in seconds and produces a fully structured reference. You don't need to
maintain a manifest of your public symbols; Great Docs figures it out from your code.

To preview what Great Docs will find without generating any files, run `great-docs scan` in your
project directory. This lists every discovered export grouped by type, and marks which items are
already included in your `reference` config. Add `--verbose` to see individual methods on each
class.

### Static Analysis Benefits

Great Docs uses static analysis rather than importing your package. This means:

- **No side effects**: your code isn't executed during discovery
- **No import errors**: missing dependencies won't break documentation
- **Faster discovery**: no need to set up a complete environment
- **Safer**: works even if your package has complex initialization

Because discovery never executes your code, you can generate documentation in CI environments,
containers, or any machine where your package's runtime dependencies aren't installed.

## What Gets Documented

By default, Great Docs documents everything it discovers in your package's public API. These
discovered items are the package's *documentable objects*: any public class, function, constant, or
type alias that Great Docs can identify through static analysis. Each documentable object is
classified into one of the following 13 object types:

**Class-like types**

- **Classes**: regular public classes with their methods
- **Dataclasses**: classes decorated with `@dataclass`
- **Abstract Classes**: classes inheriting from `ABC` or using `ABCMeta`
- **Protocols**: structural typing protocols (`typing.Protocol` subclasses)
- **Enumerations**: `Enum` subclasses
- **Exceptions**: `Exception` and `BaseException` subclasses
- **Named Tuples**: `NamedTuple` definitions
- **Typed Dicts**: `TypedDict` definitions

**Function-like types**

- **Functions**: synchronous public functions
- **Async Functions**: functions defined with `async def`

**Data types**

- **Constants**: module-level constants and data
- **Type Aliases**: type alias definitions (including `TypeVar`)

**Other**

- **Other**: anything that doesn't fit the above categories

Each type is placed into its own section in the generated reference and receives a distinct visual
badge (see [Type Labels](#type-labels) below).

### Exclusion Rules

Not everything in your package's namespace belongs in the API reference. Internal wiring like CLI
entry points, logging setup, and utility modules are implementation details that would clutter the
documentation without helping users. Great Docs automatically excludes a set of common names that
almost never represent public API:

```python
# These are auto-excluded:
main        # CLI entry points
cli
version     # Version metadata
VERSION
core        # Internal modules
utils
helpers
logger      # Logging
log
```

To exclude additional names from `init` and `scan`, add them to the `exclude` list in
`great-docs.yml`:

```{.yaml filename="great-docs.yml"}
exclude:
  - InternalHelper
  - deprecated_function
```

Once you have a `reference` config in `great-docs.yml`, you control exactly what gets documented by
listing items there. The `exclude` setting only affects what `great-docs init` discovers when
generating your initial config. Between the built-in exclusions and the explicit list, you can keep
the reference focused on the symbols your users actually need.

## Smart Method Handling

Large classes with many methods can create overwhelming documentation. Great Docs handles this
intelligently by separating methods into their own pages when a class exceeds a threshold.

### Default Behavior

By default, classes with **more than 5 methods** are split: the class itself gets one page, and each
method gets its own page in a companion "Methods" section. Classes with 5 or fewer methods keep
their methods inline on the class page.

### Configuring the Threshold

You can control this behavior with the `inline_methods` setting in `great-docs.yml`:

```{.yaml filename="great-docs.yml"}
# Keep the default (split above 5 methods)
inline_methods: 5

# Custom threshold: split above 10 methods
inline_methods: 10

# Always inline: never split methods to separate pages
inline_methods: true

# Always split: every class gets separate method pages
inline_methods: false
```

| Value | Behavior |
| --- | --- |
| `true` | Methods always stay inline on the class page, regardless of count |
| `false` | Methods always get their own pages (even for classes with 1–2 methods) |
| Integer `N` | Methods stay inline for classes with ≤N methods; classes with >N get split (default: `5`) |

The examples below show what Great Docs generates in `_quarto.yml`. This file is regenerated on
every build, so don't edit it by hand. Use `inline_methods` in `great-docs.yml` to control the
behavior and let the build produce the right output.

### Small Classes (≤ threshold)

When a class has fewer methods than the threshold, all of its methods appear directly on the class
page. Readers see everything in one place without navigating between pages. In the generated
`_quarto.yml`, the class is listed as a simple entry:

```{.yaml filename="_quarto.yml"}
sections:
  - title: Classes
    contents:
      - MySmallClass  # Methods shown inline
```

This keeps the sidebar compact and works well for classes where the full method list fits
comfortably on a single page.

### Large Classes (> threshold)

When a class exceeds the threshold, Great Docs automatically splits it in the generated
`_quarto.yml`. The methods are pulled out into a dedicated "Methods" section with individual pages,
and the class entry suppresses inline method documentation so readers aren't overwhelmed:

```{.yaml filename="_quarto.yml"}
sections:
  - title: Classes
    contents:
      - name: MyLargeClass
        members: []  # Suppresses inline methods

  - title: MyLargeClass Methods
    desc: Methods for the MyLargeClass class
    contents:
      - MyLargeClass.method_one
      - MyLargeClass.method_two
      # ... all methods listed individually
```

Each method gets its own sidebar entry and its own page, making it easier to link to specific
methods and to find them through search.

### When to Adjust

The right setting depends on how users interact with your API documentation:

- set `inline_methods: true` if your classes have many methods but users typically need to see them
all at once (e.g., configuration objects, builder patterns).
- set `inline_methods: false` if every method deserves its own discoverable page (e.g., a large
framework API where methods are searched individually).
- set a higher number (e.g., `10` or `15`) if your classes tend to have moderate method counts and the
default of `5` splits too aggressively.

When in doubt, start with the default and adjust once you see how your rendered documentation feels
to navigate.

## API Organization

The auto-generated reference is organized into sections by object type. This works well out of the
box, but as your package grows you may want to group exports by domain rather than by type. Great
Docs gives you full control over the section structure through the `reference` config in
`great-docs.yml`, from simple title changes to completely custom groupings.

### Default Sections

Great Docs creates sections automatically based on what it discovers. Only non-empty sections
appear, so if your package has no enumerations or protocols, those sections are simply omitted. Here
is the full set of possible sections:

| Section | Description |
| --- | --- |
| **Classes** | Regular public classes |
| **Dataclasses** | Data-holding classes |
| **Abstract Classes** | Abstract base classes |
| **Protocols** | Structural typing protocols |
| **Enumerations** | Enum types |
| **Exceptions** | Exception classes |
| **Named Tuples** | NamedTuple types |
| **Typed Dicts** | TypedDict types |
| **Functions** | Synchronous functions |
| **Async Functions** | Asynchronous functions (`async def`) |
| **Constants** | Module-level constants and data |
| **Type Aliases** | Type alias definitions |
| **Other** | Additional exports |
| **[ClassName] Methods** | Created for classes exceeding the `inline_methods` threshold |

A typical package might only produce a few of these (e.g., Classes, Functions, and Constants). The
section structure is automatically tailored to your package's contents.

You're encouraged to customize the organization using the `reference` config in `great-docs.yml` to
create sections that better reflect your package's domain.

### Custom Organization with `reference` Config

The default sections group exports by type, but your users probably think about your API in terms of
what it does, not what kind of Python object each export is. A data validation library might group
things into "Schema Definition", "Validators", and "Error Handling" rather than "Classes",
"Functions", and "Exceptions". Custom organization lets you tell a story with your API reference,
guiding readers to the right part of the documentation based on what they are trying to accomplish.

You can explicitly control the structure in `great-docs.yml`:

```{.yaml filename="great-docs.yml"}
reference:
  - title: User Management
    desc: Functions for managing users
    contents:
      - create_user
      - delete_user
      - update_user

  - title: Authentication
    desc: Functions for authentication
    contents:
      - login
      - logout
```

Items appear in the order listed within each section. This explicit configuration gives you complete
control over how your API documentation is organized.

One thing to watch out for: the names in `contents` must match your package's actual public API
exactly. A misspelled name, a name that was renamed or removed, or a name that appears in the
`exclude` list will silently produce a missing or empty reference page. If a page doesn't render as
expected after a build, check that the name in your `reference` config matches what your package
exports.

### Custom Title and Description

You can customize the heading and introductory text of the API reference page using the `title` and
`desc` keys:

```{.yaml filename="great-docs.yml"}
reference:
  title: "API Docs"
  desc: >
    Welcome to the API documentation. This reference covers all public
    classes and functions available in the package.
```

When set, the `title` replaces the default "Reference" heading on the API index page and in the
navigation bar. The `desc` text appears as a paragraph immediately below the heading, providing
context before the section listings.

Without explicit `sections`, sections are auto-generated from your package's public API. You can
also combine `title`/`desc` with explicit section ordering using a `sections` key:

```{.yaml filename="great-docs.yml"}
reference:
  title: "API Reference"
  desc: "Complete reference for all public symbols."
  sections:
    - title: Core
      desc: Primary classes
      contents:
        - MyClass
        - Config
    - title: Utilities
      desc: Helper functions
      contents:
        - format_output
        - parse_input
```

If neither `title` nor `desc` is set, the page heading defaults to "Reference" with no introductory
text.

### Controlling Method Documentation

By default, class methods are documented inline on the class page. To exclude methods from
documentation (for example, if you want to document them separately elsewhere), use
`members: false`:

```{.yaml filename="great-docs.yml"}
reference:
  - title: Core Classes
    desc: Main classes for the package
    contents:
      - name: MyClass
        members: false       # Don't document methods here
      - SimpleClass          # Methods documented inline (default)

  - title: MyClass Methods
    desc: Methods for the MyClass class
    contents:
      - MyClass.method1
      - MyClass.method2
```

When `members: false` is set, only the class itself is documented. You can then place individual
methods wherever you want in your reference structure.

### Documenting Inherited Methods

By default, only methods defined directly on a class are documented. Inherited methods are excluded
unless you opt in. This keeps reference pages focused and avoids duplicating parent class methods on
every child page (especially important in deep class hierarchies where it would add significant
clutter).

If your class hierarchy uses inheritance and you want child classes to show inherited methods, there
are two approaches.

**Explicit member list.** List the methods you want documented (including inherited ones) in the
`members` key:

```{.yaml filename="great-docs.yml"}
reference:
  - title: API
    contents:
      - BaseProcessor
      - name: AdvancedProcessor
        members:
          - process        # own method
          - validate       # inherited from BaseProcessor
          - reset          # inherited from BaseProcessor
```

This gives you full control over which inherited methods appear and in what order.

**Auto-include inherited methods.** Use `include_inherited: true` to automatically document all
inherited methods without listing them explicitly:

```{.yaml filename="great-docs.yml"}
reference:
  - title: Shapes
    contents:
      - Shape
      - name: Circle
        include_inherited: true  # includes area(), perimeter(), describe() from Shape
```

With this flag, the child class page will show its own methods plus all public methods inherited
from parent classes.

::: {.callout-tip}
You can combine both approaches. Use `include_inherited: true` for convenience, or provide an
explicit `members` list when you want to cherry-pick specific inherited methods or control ordering.
:::

### Excluding Items with `exclude`

To exclude items from documentation, add them to the `exclude` list in `great-docs.yml`:

```{.yaml filename="great-docs.yml"}
exclude:
  - internal_helper
  - deprecated_function
```

Items in the exclude list won't appear when running `great-docs init` or `great-docs scan`, and
won't be documented even if discovered.

## Source Code Links

Great Docs automatically adds "source" links to each documented item, pointing to the exact line
numbers on GitHub.

### How It Works

1. Great Docs detects your GitHub repository from `pyproject.toml` or `.git`
2. For each documented item, it finds the source file and line numbers
3. Links are generated pointing to `github.com/owner/repo/blob/branch/file#L1-L10`

Source links let readers jump straight from the documentation to the implementation, which is
especially valuable during code reviews and debugging.

### Configuration

```{.yaml filename="great-docs.yml"}
source:
  # Use a specific branch (default: auto-detected)
  branch: main

  # Disable source links
  enabled: false
```

## Submodule Introspection

When your package exports submodules (e.g., `dateutil.parser`, `dateutil.tz`), Great Docs
automatically drills into each module to discover its public classes, functions, and constants. This
means you can list a module name in your `reference` config and Great Docs will expand it into all
of its individual members.

For example, if your package exports a `parser` submodule containing a `parse()` function, a
`parser` class, and a `ParserError` exception, writing:

```{.yaml filename="great-docs.yml"}
reference:
  - title: Parser
    desc: Date string parsing
    contents:
      - parser
```

will automatically expand to document `parser.parse`, `parser.parser`, `parser.ParserError`, and all
other public members of the `parser` module. Each member is classified into the correct object type
and receives appropriate visual treatment.

This is particularly useful for packages like `dateutil` that organize their API into topical
submodules rather than exporting everything from the top-level `__init__.py`.

## Cross-Referencing

Great Docs includes a linking system (GDLS) that automatically creates clickable navigation between
your API reference pages. It supports `%seealso` directives in docstrings, inline interlinks using
Markdown syntax, and automatic code-to-link conversion for inline code that matches documented
symbols.

See [Cross-Referencing](cross-referencing.qmd) for the full guide to all linking features.

## Docstring Directives

Great Docs directives add document structure and control API-reference behavior. Write directives
as `%<directive>` in NumPy-, Google-, or Sphinx-style docstrings.

Great Docs supports two kinds of directives:

- `%nodoc` excludes an object, and `%seealso` adds cross-references.
- Callout directives add version annotations and admonitions.

### Callout Directives

Short callouts can put their content on the directive line:

```python
%warning This operation modifies the input.
%versionadded 2.0
%deprecated 3.0 Use `new_function` instead.
```

For longer content, indent the body below the directive:

```python
%versionchanged 2.1
    Now returns a copy.

%warning
    This operation modifies the input.

    Make a copy first if mutation is undesirable.
```

An inline body may also continue on indented lines. Great Docs preserves Markdown and paragraph
breaks within the body. Version directives use the first argument as the version and the remaining
content as the optional description.

| Directive | Appearance |
| --- | --- |
| `%versionadded 2.0` | Quarto `note` callout titled "Added in version 2.0" |
| `%versionchanged 3.1` | Quarto `note` callout titled "Changed in version 3.1" |
| `%deprecated 2.6` | Quarto `warning` callout titled "Deprecated since version 2.6" |
| `%note ...` | Quarto `note` callout |
| `%warning ...` | Quarto `warning` callout |
| `%caution ...` | Quarto `caution` callout |
| `%danger ...` | Quarto `important` callout |
| `%important ...` | Quarto `important` callout |
| `%tip ...` | Quarto `tip` callout |
| `%hint ...` | Quarto `tip` callout |

### Sphinx Compatibility

Great Docs also accepts the equivalent Sphinx/RST forms:

```rst
.. versionadded:: 2.0

.. versionchanged:: 2.1

    Now returns a copy.

.. warning:: This operation modifies the input.
```

Both syntaxes produce the same callouts. Use Sphinx syntax when the same docstrings must work with
both Great Docs and Sphinx; otherwise, prefer Great Docs `%` directives.

### Sphinx Cross-Reference Roles

Sphinx roles like `:py:class:`, `:func:`, and `:exc:` are converted into plain inline code
formatting. For example, `` :py:exc:`ValueError` `` becomes `ValueError`, and
`` :py:class:`datetime.datetime` `` becomes `datetime.datetime`. Function and method roles
automatically receive trailing `()` to indicate they are callable, so `` :func:`my_function` ``
renders as `my_function()` and `` :meth:`MyClass.run` `` renders as `MyClass.run()`.

## Visual Enhancements

Great Docs applies consistent styling to your API documentation, making it easier to scan and
understand at a glance.

### Type Labels {#type-labels}

Each documented item displays a colored badge indicating its object type:

| Type | Color | Used For |
| --- | --- | --- |
| **class** | Indigo | Classes, dataclasses, protocols, ABCs, named tuples, typed dicts |
| **exception** | Red | Exception classes |
| **enum** | Indigo | Enum types |
| **function** | Violet | Functions (shown with trailing `()`) |
| **method** | Cyan | Class methods (shown as `Class.method()`) |
| **constant** | Amber | Module-level constants |
| **type alias** | Green | Type alias definitions |
| **other** | Gray | Uncategorized exports |

Great Docs uses a metadata file (`_object_types.json`) generated during the build to determine the
correct badge for each item. This ensures accurate classification even for edge cases like constants
that start with an uppercase letter or functions named after classes.

### Code Styling

The documentation applies careful typography to code elements throughout. Function signatures use
monospace fonts for clarity, and type annotations are formatted to be easily readable. Parameter
lists have improved spacing that makes long signatures scannable. Code blocks benefit from enhanced
syntax highlighting that matches the overall site theme. Together, these refinements make technical
content more approachable.

### Responsive Design

API documentation needs to work on devices of all sizes, from large desktop monitors to phones.
Great Docs optimizes the layout for each screen size with mobile-friendly navigation that adapts to
touch interactions. The sidebar becomes collapsible on smaller screens, and typography scales
appropriately to remain readable. Whether you're at your desk or reviewing docs on your phone during
a commute, the experience remains consistent.

## Sidebar Filter

For packages with many exports, navigating the sidebar can become cumbersome. Great Docs addresses
this with a built-in search filter that appears automatically when your API has 20 or more items.

The filter provides instant results as you type, narrowing down the sidebar to show only matching
items. A count indicator shows how many items match your search out of the total. The section
structure is preserved during filtering, so you maintain context about where items live in your API
hierarchy.

You can customize when the filter appears in your `great-docs.yml`:

```{.yaml filename="great-docs.yml"}
sidebar_filter:
  enabled: true
  min_items: 15   # Show filter with 15+ items
```

Set `enabled: false` to disable it entirely, or adjust `min_items` to change the threshold.

## Refreshing API Documentation

When your package's API changes, rebuild with:

```{.bash filename="Terminal"}
great-docs build
```

This automatically re-discovers exports and updates the configuration.

For faster builds when only documentation content changed (not API):

```{.bash filename="Terminal"}
great-docs build --no-refresh
```

Either way, the rendered output reflects the current state of your package. You never need to
manually edit generated reference pages.

## Migrating from quartodoc

If you have an existing site built with [quartodoc](https://machow.github.io/quartodoc/), switching
to Great Docs is straightforward. The two tools share similar ideas (sections, contents lists,
Quarto rendering) but differ in where configuration lives and how much you need to specify by hand.

### Key Differences

| | **quartodoc** | **Great Docs** |
| --- | --- | --- |
| Config file | `_quarto.yml` (under a `quartodoc:` key) | `great-docs.yml` |
| API discovery | Manual: you list every object | Automatic: discovers your public API from source |
| Build command | `quartodoc build` then `quarto render` | `great-docs build` (handles both steps) |
| Preview command | `quarto preview` | `great-docs preview` |
| Generated output | `reference/` directory with `.qmd` files and `_sidebar.yml` | `great-docs/` directory (ephemeral, gitignored) |
| Sidebar | You include a generated `_sidebar.yml` via `metadata-files` | Managed automatically |

### Step-by-Step Migration

1. **Install Great Docs** and run `great-docs init` in your project root. This auto-discovers your
   package and creates `great-docs.yml`.

2. **Translate your reference layout.** The `sections` structure maps almost directly. A quartodoc
   config like this:

   ```{.yaml filename="_quarto.yml (quartodoc)"}
   quartodoc:
     package: my_package
     sections:
       - title: Core
         desc: Primary interface
         contents:
           - MyClass
           - helper_function
       - title: Utilities
         desc: Utility helpers
         contents:
           - format_output
   ```

   becomes this in Great Docs:

   ```{.yaml filename="great-docs.yml"}
   reference:
     sections:
       - title: Core
         desc: Primary interface
         contents:
           - MyClass
           - helper_function
       - title: Utilities
         desc: Utility helpers
         contents:
           - format_output
   ```

   The section structure (`title`, `desc`, `contents`) is the same and you just move it from
   `quartodoc.sections` in `_quarto.yml` to `reference.sections` in `great-docs.yml`.

   One syntax difference: quartodoc uses `members: []` (an empty list) to suppress inline method
   documentation on a class, while Great Docs uses `members: false`. So a quartodoc entry like:

   ```yaml
   - name: MyClass
     members: []
   ```

   becomes:

   ```yaml
   - name: MyClass
     members: false
   ```

3. **Move your user guide pages.** If you have narrative `.qmd` files (tutorials, guides, etc.),
   move them into a top-level `user_guide/` directory. Great Docs expects user guide content there
   rather than scattered alongside `_quarto.yml`. See [User Guides](user-guides.qmd) for naming
   conventions and sidebar ordering.

4. **Clean up quartodoc artifacts.** Great Docs generates its own `_quarto.yml` inside the
   ephemeral `great-docs/` build directory on every build, so you don't need to edit or keep your
   old `_quarto.yml`. The main thing to do is delete the `reference/` directory that quartodoc
   generated (but check it first for any hand-written `.qmd` content you want to migrate into
   your `user_guide/` directory or `great-docs.yml` reference config).

5. **Build and preview.** Run `great-docs build` followed by `great-docs preview`. Your reference
   pages should render with the same content, now with Great Docs' enhanced styling and features.

## Next Steps

Great Docs handles the tedious parts of API documentation (discovery, classification, layout,
linking) so you can focus on writing clear docstrings. Whether your package exports a handful of
functions or hundreds of classes, the reference section stays organized and up to date.

- [Writing Docstrings](writing-docstrings.qmd) covers docstring format, sections, executable
examples, and `%nodoc`
- [Cross-Referencing](cross-referencing.qmd) covers the full linking system (GDLS) for connecting
API pages
- [CLI Documentation](cli-documentation.qmd) covers Click CLI documentation
- [User Guides](user-guides.qmd) explains how to add narrative documentation
- [Configuration](configuration.qmd) covers all `great-docs.yml` options
