Skip to main content

CLI reference

The OpenDocs CLI is the supported integration layer for AI agents, scripts, and humans working from Markdown files.

npm install -g @opendocs.cc/cli
opendocs login --browser

For non-interactive agents and CI, prefer:

export OPENDOCS_API_KEY=od_live_xxxxx
opendocs whoami --json

Global options

OptionApplies toNotes
--jsonAll commandsMachine-readable stdout. Errors are written to stderr as JSON when possible.
--api-url <url>All commandsOverride the default API host, https://api.opendocs.cc.
-h, --helpAll commandsShow command help.
-V, --versionRoot commandShow CLI version.

Environment variables:

VariableNotes
OPENDOCS_API_KEYAPI key used by opendocs login and commands in headless environments.
OPENDOCS_API_URLDefault API URL override for local/staging environments.
OPENDOCS_WEB_URLWeb app URL override for opendocs login --browser.

Exit behavior

Exit codeMeaning
0Command succeeded. For batch commands, all items succeeded.
Non-zeroCommand failed, or a batch completed with at least one failed item.

In --json mode, successful commands write one JSON object to stdout. Errors write a JSON object to stderr when the CLI can classify the failure:

{ "error": "document_limit", "message": "Your free plan has 0 slots left." }

opendocs login

Authenticate and store local config in ~/.config/opendocs/config.json.

opendocs login --browser
opendocs login --key od_live_xxxxx
OPENDOCS_API_KEY=od_live_xxxxx opendocs login

opendocs login --browser opens OpenDocs in your browser and creates a normal API key after you approve the CLI. If you are already signed in, the browser shows the current account and workspace so you can confirm you are not authorizing the wrong account. Use --key or OPENDOCS_API_KEY for agents, CI, SSH sessions, and other headless environments.

Do not run bare opendocs login from an agent. Without --key or OPENDOCS_API_KEY, it waits for an interactive hidden prompt.

Useful flags:

FlagNotes
--browserOpen a browser and authorize the CLI from your signed-in OpenDocs account.
--key <key>API key to validate and store.
--web-url <url>Override the web app used by --browser; useful for local/staging.
--jsonPrint the saved account/workspace state as JSON.

JSON shape:

{
"success": true,
"apiUrl": "https://api.opendocs.cc",
"userId": "usr_123",
"username": "ada",
"workspaceId": "ws_123",
"workspaceName": "Acme Docs",
"workspaceSlug": "acme-docs"
}

opendocs whoami

Show the authenticated account, active workspace, active project, API URL, and quota.

opendocs whoami --json

JSON shape:

{
"userId": "usr_123",
"onboarding": {
"username": "ada",
"workspace": {
"id": "ws_123",
"name": "Acme Docs",
"slug": "acme-docs"
}
},
"quota": {
"documents": {
"plan": "pro",
"limit": null,
"used": 42,
"remaining": null
}
}
}

Agents should use this before publishing when they need to confirm the active workspace, active project, or quota.

opendocs project

Manage projects in the active workspace. Projects let agents keep a related batch of documents separate from the workspace Default project.

opendocs project list --json
opendocs project current --json
opendocs project create "Launch docs" --slug launch-docs --use --json
opendocs project use launch-docs --json
opendocs project rename launch-docs --name "Launch documentation" --json
opendocs project delete launch-docs --yes --json

Default project documents use /workspace/slug. Non-default projects use /workspace/projects/project/slug. Deleting a project only works when it is non-default and empty.

opendocs publish

Publish one or more Markdown files.

opendocs publish doc.md --json
opendocs publish docs/*.md --tags api-docs --json
opendocs publish ./vault --tags obsidian-import --json
opendocs publish report.md --export pdf --json

Flags:

FlagNotes
--title <title>Override title. Single-file only.
--slug <slug>Request a custom slug. Single-file only.
--visibility <level>private, workspace, or public. Defaults to workspace.
--confirm-publicRequired with --visibility public.
--tags <tags>Comma-separated tags. Max 20 tags per post.
--project <slug-or-id>Publish to a specific project instead of the active project.
--export <format>Export successful publishes to pdf or docx.
--jsonRecommended for agents.

Limits:

LimitValue
Markdown size per file1 MB
Files per CLI invocation500
Documents per publish API batch25, auto-chunked by the CLI
Local images per document30
Local image size10 MB each

Folder inputs are scanned recursively. The CLI publishes .md files and skips .obsidian, .trash, .git, and node_modules, which makes Obsidian vault imports a single command.

Single-file JSON:

{
"postId": "post_123",
"slug": "launch-note",
"url": "/acme-docs/launch-note",
"title": "Launch note",
"projectSlug": "default",
"tags": ["launch"]
}

Batch JSON:

{
"total": 2,
"succeeded": 2,
"failed": 0,
"results": [
{
"success": true,
"file": "docs/intro.md",
"postId": "post_123",
"slug": "intro",
"url": "/acme-docs/intro",
"title": "Intro"
}
]
}

Publish-plus-export JSON includes an export block with local output paths:

{
"postId": "post_123",
"url": "/acme-docs/report",
"export": {
"format": "pdf",
"path": "report.pdf"
}
}

opendocs update

Create a new version of an existing published post while keeping the same URL.

opendocs update revised.md --post-id launch-note --json

--post-id accepts either the UUID or slug. Slug inputs are resolved inside the active project.

Flags:

FlagNotes
--post-id <id-or-slug>Required.
--title <title>Override the title.
--visibility <level>Optional. Omit to preserve current visibility.
--confirm-publicRequired when changing to public.
--tags <tags>Replace tags with this comma-separated list. Omit to preserve current tags.

JSON shape:

{
"postId": "post_123",
"versionId": "ver_456",
"versionNumber": 4,
"slug": "launch-note",
"title": "Launch note",
"visibility": "workspace",
"tags": ["release"]
}

opendocs list

List posts authored by the signed-in user.

opendocs list --json
opendocs list --all --limit 100 --json
opendocs list --tag api-docs --json

Flags:

FlagNotes
--page <n>Defaults to 1.
--limit <n>Defaults to 20, max 100.
--tag <tag>Filter by normalized tag.
--allList across all workspaces. Default is active workspace only.

JSON shape:

{
"posts": [
{
"id": "post_123",
"title": "Launch note",
"slug": "launch-note",
"visibility": "workspace",
"isPublished": true,
"workspaceId": "ws_123",
"workspaceSlug": "acme-docs",
"tags": ["release"],
"updatedAt": "2026-04-25T12:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 1,
"totalPages": 1
},
"scope": "workspace",
"workspaceSlug": "acme-docs"
}

opendocs get

Inspect one post by UUID or slug.

opendocs get launch-note --json

JSON shape:

{
"post": {
"id": "post_123",
"slug": "launch-note",
"title": "Launch note",
"url": "/acme-docs/launch-note",
"visibility": "workspace",
"isPublished": true,
"versionNumber": 4,
"tags": ["release"]
}
}

opendocs pull

Download raw Markdown for one post, one project, or the active workspace.

opendocs pull launch-note
opendocs pull launch-note --output docs/launch-note.md
opendocs pull launch-note --stdout
opendocs pull --project --output ./docs
opendocs pull --project launch-docs --tag release
opendocs pull --workspace --output ./opendocs
opendocs pull --workspace --dry-run

For single-post pulls, --output is a file path. For bulk pulls, --output is a directory. Project pulls write files directly into that directory. Workspace pulls write Default project docs at the root and non-default project docs under projects/<project-slug>/.

Bulk pulls refuse to overwrite existing files unless --overwrite is passed. Use --dry-run to preview the file plan before writing.

Flags:

FlagNotes
--output <path>Destination file for one post, or destination directory for bulk pulls.
--stdoutPrint one post's Markdown to stdout. Useful for agents.
--project [slug-or-id]Pull the active project, or a specific project.
--workspacePull every project in the active workspace.
--tag <tag>Filter bulk pulls by tag.
--overwriteReplace existing files during bulk pulls.
--dry-runPreview a bulk pull without writing files.

opendocs export

Export one or more published posts to PDF or DOCX.

opendocs export launch-note --format pdf
opendocs export intro guide api --format pdf --output ./exports

Flags:

FlagNotes
-f, --format <format>pdf or docx.
-o, --output <path>File path for one export; directory for batch export.
--stdoutBinary stdout. Single post only.
--landscapeLandscape PDF.
--accent-color <hex>Override export accent color.

Batch export accepts up to 10 post IDs/slugs per command.

opendocs visibility

Change who can read a post without uploading new Markdown.

opendocs visibility launch-note private
opendocs visibility launch-note workspace
opendocs visibility launch-note public --confirm-public

Levels: private, workspace, public.

opendocs unpublish

Hide a post without deleting its content or version history.

opendocs unpublish launch-note

Unpublishing is reversible by publishing again, and it frees a Free-plan document slot because quota counts only currently published posts.

opendocs delete

Permanently delete a post.

opendocs delete launch-note --yes

Use --yes or -y from agents and scripts. Without it, non-interactive contexts fail with confirm_required before making a network call.

opendocs workspace list

List workspaces the account belongs to.

opendocs workspace list --json
opendocs workspace ls --json

JSON shape:

{
"workspaces": [
{
"id": "ws_123",
"name": "Acme Docs",
"slug": "acme-docs",
"role": "owner"
}
],
"activeSlug": "acme-docs"
}

opendocs workspace use

Switch the active workspace in local CLI config.

opendocs workspace use acme-docs --json
opendocs workspace switch acme-docs --json

JSON shape:

{
"success": true,
"workspaceId": "ws_123",
"workspaceName": "Acme Docs",
"workspaceSlug": "acme-docs"
}

Switching is local only. It does not affect the dashboard's active workspace.

opendocs agent

Print static, package-bundled instructions for AI agents. This command does not require login and does not fetch remote content.

opendocs agent # concise, high-signal reference
opendocs agent --full # full bundled SKILL.md
opendocs agent --api # API-only reference
opendocs agent --cli # CLI-only reference

With --json, the response shape is:

{
"variant": "api",
"version": "0.1.x",
"content": "# OpenDocs Public API Agent Reference\n..."
}

opendocs logout

Remove local credentials.

opendocs logout

Common CLI errors

ErrorRecovery
auth_expiredCreate a new API key and run opendocs login --key ....
document_limitUpgrade, unpublish old docs, or publish only the files that fit.
doc_too_largeSplit the Markdown file.
too_many_filesSplit a >500-file publish into multiple invocations.
too_many_postsSplit export batches into groups of 10.
confirm_public_requiredRe-run with --confirm-public only after explicit consent.
confirm_requiredAdd --yes for delete in non-interactive contexts.
not_a_memberRun opendocs workspace list --json, choose an available slug, then switch.
image_upload_failedFix or remove the local image reference and retry.
export_failedRetry opendocs export; the publish usually already succeeded.