---
title: Validate documentation in CI
description: Catch broken links, invalid OpenAPI specifications, and content issues before they ship.
url: https://pr-13-a9c4e9fe1b6c.thally.app/guides/ci-checks
---

# Validate documentation in CI

Catch broken links, invalid OpenAPI specifications, and content issues before they ship.

`thally check` lints your docs and, with `--ci`, fails a pull request when something
is broken, so CI can stop the change before it reaches production.

## What it checks

- **Content** — orphan pages (not in `docs.json`), missing `title`/`description`, thin pages, pages in nav with no file.
- **Internal links & anchors** — every `/page` link resolves to a real page, and every `#heading` anchor exists. Links inside code blocks are ignored (they're examples).
- **OpenAPI** — your API spec parses and has the required structure (`openapi` version, `info`, valid `paths`).

> **Note:**
External links are skipped by default for deterministic, network-free CI. Pass
`--external` to HEAD-check them too.

## Run it

```bash
npx --yes @thallylabs/cli@latest check           # human-readable report
npx --yes @thallylabs/cli@latest check --fix     # auto-add orphan pages to navigation
npx --yes @thallylabs/cli@latest check --ci .    # GitHub annotations + non-zero exit on errors
```

The scoped package name is required because the unscoped `thally` package is
not published. `npx` downloads the current CLI when the project has no local
copy.

## In GitHub Actions

New projects include a pinned checker under `.github/thally-tooling` and run it
on every pull request. The pinned CI path avoids downloading a mutable package
in a credential-bearing workflow:

```yaml
- name: Install pinned content tooling
  run: npm ci --ignore-scripts --prefix .github/thally-tooling

- name: thally check
  run: .github/thally-tooling/node_modules/.bin/thally check --ci .
```

Warnings (orphans, thin pages) are reported but don't fail the build; **errors**
(broken links, missing pages, invalid OpenAPI) do.