Drop these files into your repository to run DocsCI on every push. All templates call the same public API — pick the one that fits your stack.
DOCSCI_TOKEN as a secret and DOCSCI_PROJECT_ID as a variable in your CI settingsAPI tokens: coming soon — use your Supabase session cookie for now (see curl script below)
Add to .github/workflows/docsci.yml
# .github/workflows/docsci.yml
name: DocsCI
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
docs-ci:
name: Verify docs with DocsCI
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Run DocsCI
id: docsci
run: |
set -euo pipefail
RESULT=$(curl -sf -X POST https://snippetci.com/api/runs/queue \
-H "Authorization: Bearer ${{ secrets.DOCSCI_TOKEN }}" \
-H "Content-Type: application/json" \
--max-time 120 \
-d '{"mode":"repo","repo_id":"${{ vars.DOCSCI_PROJECT_ID }}","branch":"${{ github.ref_name }}","commit_sha":"${{ github.sha }}"}')
STATUS=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('status','unknown'))")
FINDINGS=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('finding_count',0))")
echo "status=$STATUS" >> "$GITHUB_OUTPUT"
echo "findings=$FINDINGS" >> "$GITHUB_OUTPUT"
- name: Fail if docs have errors
if: steps.docsci.outputs.status == 'failed'
run: |
echo "::error::DocsCI found ${{ steps.docsci.outputs.findings }} issue(s)."
exit 1Works in any CI system (CircleCI, Bitbucket Pipelines, Jenkins, Buildkite) or locally. Save as scripts/run-docsci.sh.
#!/usr/bin/env bash
# run-docsci.sh — works in any CI or locally
# Export: DOCSCI_TOKEN, DOCSCI_PROJECT_ID
set -euo pipefail
BRANCH="${DOCSCI_BRANCH:-$(git rev-parse --abbrev-ref HEAD)}"
COMMIT="${DOCSCI_COMMIT:-$(git rev-parse HEAD)}"
RESULT=$(curl -sf -X POST https://snippetci.com/api/runs/queue \
-H "Authorization: Bearer $DOCSCI_TOKEN" \
-H "Content-Type: application/json" \
--max-time 120 \
-d "{\
\"mode\":\"repo\",\
\"repo_id\":\"$DOCSCI_PROJECT_ID\",\
\"branch\":\"$BRANCH\",\
\"commit_sha\":\"$COMMIT\"\
}")
STATUS=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('status','unknown'))")
FINDINGS=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('finding_count',0))")
echo "DocsCI $STATUS — $FINDINGS finding(s)"
[ "$STATUS" = "passed" ] && exit 0 || exit 1Environment variables
DOCSCI_TOKEN — required, your API token
DOCSCI_PROJECT_ID — required, project UUID
DOCSCI_BRANCH — optional, defaults to current git branch
DOCSCI_COMMIT — optional, defaults to HEAD SHA
DOCSCI_FAIL_FAST — set to "0" to exit 0 on findings
DOCSCI_TIMEOUT — curl timeout seconds (default: 120)
Add to .gitlab-ci.yml
# .gitlab-ci.yml
stages: [docs-ci]
docsci:
stage: docs-ci
image: python:3.11-alpine
before_script: [apk add --no-cache curl]
script:
- |
RESULT=$(curl -sf -X POST https://snippetci.com/api/runs/queue \
-H "Authorization: Bearer $DOCSCI_TOKEN" \
-H "Content-Type: application/json" \
--max-time 120 \
-d "{\"mode\":\"repo\",\"repo_id\":\"$DOCSCI_PROJECT_ID\",\"branch\":\"$CI_COMMIT_BRANCH\",\"commit_sha\":\"$CI_COMMIT_SHA\"}")
STATUS=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('status','unknown'))")
FINDINGS=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('finding_count',0))")
echo "DocsCI $STATUS — $FINDINGS finding(s)"
[ "$STATUS" = "failed" ] && exit 1 || exit 0
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'Drop in your repo root to control timeouts, languages, file globs, and security. See the getting started guide for all options.
# docsci.yml — place in your repo root version: 1 docs: path: docs include: ["docs/**/*.md"] exclude: ["docs/internal/**"] openapi: path: openapi.yaml snippets: timeout_seconds: 20 languages: [python, javascript, typescript] skip_patterns: ["# docsci: skip"] security: network_isolated: false allowlist: ["api.example.com"] checks: accessibility: true copy_lint: true drift_detection: true snippets: true
All templates are available via the API — useful for automation:
# List all templates curl https://snippetci.com/api/templates # Download a specific template curl https://snippetci.com/api/templates?id=github-actions&download=1 > .github/workflows/docsci.yml curl https://snippetci.com/api/templates?id=curl-fallback&download=1 > scripts/run-docsci.sh curl https://snippetci.com/api/templates?id=docsci-yml&download=1 > docsci.yml
If you're using pytest doctest, Jupyter notebooks, or custom test scripts to verify code examples, our migration guide shows you how to replace them with DocsCI in under an hour.
Read the migration guide →