All guides
Integration

Outworx CLI — push specs from anywhere

Publish OpenAPI / Swagger / GraphQL specs to Outworx Docs from your laptop or any CI provider. One command, zero install graph, scriptable exit codes.

If your hosted docs lag behind your spec, the difference between "annoying" and "blocked at 2am" usually comes down to whether the publish step is one command or fifteen lines of curl. The Outworx CLI is the one-command path.

npx @outworx/cli push openapi.yaml --project payments-api

That's the whole thing. The CLI works on your laptop, in CI on any provider (GitHub Actions, GitLab, CircleCI, Buildkite, Jenkins…), and inside a pre-commit hook. This guide covers install, auth, configuration, and the flows worth wiring up.

Install

The CLI runs on Node.js 18.17+ and ships as an npm package.

# One-shot via npx — recommended for CI, no global state
npx @outworx/cli push ...

# Or globally
npm install -g @outworx/cli
outworx push ...

There's no Docker image, no Python wrapper, no system service to install. It's a 30KB npm package that wraps the public REST API — so anything you'd expect from the curl examples is one CLI flag away, with better error messages.

Authentication

Two token shapes — pick whichever matches your scope:

TokenPrefixScopeBest for
Personal access tokenotwx_pat_*Account-wide; acts as the user who minted itMulti-project CI, shared org secrets, preview deploys
Project upload tokenotwx_*Single project, spec upload onlyPer-repo CI on one project, contractor pushes

Mint either in Settings. The dashboard shows the plaintext once — copy it, store it as a secret, and never check it into a repo.

Pass the token via --token, but OUTWORX_TOKEN env var is preferred — flags end up in shell history and process listings, env vars don't:

export OUTWORX_TOKEN=otwx_pat_...
outworx push openapi.yaml --project payments-api

In GitHub Actions:

env:
  OUTWORX_TOKEN: ${{ secrets.OUTWORX_TOKEN }}

The push command

The CLI has one command today: push. (More are tracked but pushing specs is the 95% workflow.)

Push to the default version

outworx push openapi.yaml --project payments-api

This updates your project's current default version in place. After the push, your hosted docs reflect the new spec within seconds.

Push to a specific version

outworx push openapi.yaml --project payments-api --version v2-beta

If the version doesn't exist, it's created. Useful for cutting a v2 alongside an existing v1 without retiring the old one.

Preview push (PR-only deploys)

Preview pushes publish to /preview/<pr>, get filtered out of the public picker, never become the default, and auto-expire 14 days after the PR closes:

outworx push openapi.yaml \
  --project payments-api \
  --preview \
  --pr "$GITHUB_PR_NUMBER" \
  --commit "$GITHUB_SHA" \
  --branch "$GITHUB_HEAD_REF"

Preview pushes require a PAT (otwx_pat_*) — project upload tokens don't carry the version:write scope. The CLI rejects with a clear error if you try.

Configuration file

For repos where every push goes to the same project, drop a config file at the repo root so you don't repeat --project and --base-url on every invocation:

// outworx.json
{
  "project": "payments-api",
  "version": "v1",
  "baseUrl": "https://docs.outworx.io"
}

.outworxrc.json works too if you prefer dot-files. The CLI walks up from cwd to find the first match, so a config in your repo root applies anywhere underneath it.

Precedence (highest wins): CLI flag → env var → config file → built-in default.

Environment variables

VarEquivalent flag
OUTWORX_TOKEN--token
OUTWORX_PROJECT--project
OUTWORX_BASE_URL--base-url

OUTWORX_TOKEN is the only one most users set. The others exist for the rare case where you don't want a config file but also don't want long flag-soup commands.

Exit codes

The CLI returns standard, scriptable exit codes:

CodeMeaningWhat to do
0SuccessContinue.
1User error — bad flag, missing file, 4xx responseFix the input. Don't retry.
2Network or transient API error (5xx, ECONNREFUSED)Re-run the workflow.
3Internal errorOpen an issue with DEBUG=1 output.

Pattern-match on these in your CI's retry policy. GitHub Actions, for instance:

- uses: abdallaemadeldin/upload-spec-action@v1
  with: { token: ${{ secrets.OUTWORX_TOKEN }}, project: foo, spec: ./openapi.yaml }
- name: Notify slack on user error
  if: failure() && steps.previous.outcome == 'failure'
  run: ...

Full flag reference

outworx push <spec-file> [options]

  --project <slug>          Project slug. Required (or OUTWORX_PROJECT env, or in outworx.json).
  --version <label>         Version label. Defaults to the project's default version.
  --token <token>           PAT or upload token. Required (or OUTWORX_TOKEN env).
  --base-url <url>          API base URL. Defaults to https://docs.outworx.io.
  --preview                 Push as a PR preview (PAT-only, expires in 14 days).
  --pr <number>             Preview-only — PR number for the banner.
  --commit <sha>            Preview-only — commit SHA for the banner.
  --branch <name>           Preview-only — branch name for the banner.

  --help, -h                Show help.
  --version, -v             Show CLI version.

When to use the CLI vs the GitHub Action vs curl

  • GitHub Action (guide) — three lines of YAML. The right answer for any GitHub-hosted repo. The action wraps this CLI under the hood, so feature parity is automatic.
  • CLI — laptop pushes (debugging, one-off republishes after a git revert), non-GitHub CI (CircleCI, GitLab, Buildkite), pre-commit hooks. The CLI is also the answer when you need to script around the publish step (e.g. push to a preview, run smoke tests, then promote).
  • curl — the escape hatch when neither works. The dashboard's upload card has a pre-filled curl snippet, and the public REST API is the canonical reference if you ever need to wire Outworx into a custom tool.

What gets audited

Every successful push writes a SPEC_UPLOADED row to the audit log with the spec format, source (api), endpoint count, and the token id that performed the push. If a token leaks, you can find every action it ever took with one metadata->>token_id = '<uuid>' filter.

Troubleshooting

"Spec file not found" — the path is relative to your current working directory. In GitHub Actions, the spec path is relative to the repo root after actions/checkout. Run ls in the workflow to verify.

"Project slug is required" — pass --project, set OUTWORX_PROJECT, or drop an outworx.json in your repo root.

"Couldn't parse YAML at line N" — the parser saw something it couldn't read. Validate locally first: npx @redocly/cli lint openapi.yaml is the fastest sanity check.

"Preview pushes require a personal access token" — you tried to use a project upload token (otwx_*) with --preview. Mint a PAT (otwx_pat_*) in Settings → API tokens and use that instead.

"Network error talking to https://docs.outworx.io" — exit code 2, transient. Re-run. If it persists, check status.outworx.io.

See also

Related guides

Ship your API docs in under a minute.

Upload your OpenAPI, Swagger, or GraphQL spec and get beautiful hosted docs with AI chat and a per-project MCP server — free forever for 2 projects.