PapermarkDocs

Output contract

Machine-readable JSON envelopes, exit codes, and retryable semantics.

The CLI's machine-readable output is a stable contract. Scripts that consume papermark output should pin to CONTRACT v1; we won't break it without bumping to v2 and announcing in the changelog.

The contract is enforced when --json is set or when stdout isn't a TTY (i.e. when piped). Human-formatted output for interactive use is not a contract — it can change between minor versions.

Success envelope

{
  "ok": true,
  "data": {  },
  "meta": {
    "next_cursor": "doc_…"
  }
}
FieldRequiredNotes
okyestrue for success
datayesOperation-specific payload. For list commands, an array. For single-resource commands, an object.
metaonly for paginated listsCurrently just next_cursor; pass it back as --cursor to fetch the next page. null when there are no more pages.

Failure envelope

{
  "ok": false,
  "error": {
    "code": "AUTH_INVALID",
    "message": "Token rejected.",
    "status": 401,
    "retryable": false,
    "hint": "Run `papermark login` to refresh credentials.",
    "doc_url": "https://papermark.com/docs/cli/output-contract#auth-invalid",
    "details": {}
  }
}
FieldRequiredNotes
okyesfalse for failure
error.codeyesOne of the canonical codes below. Safe to switch on.
error.messageyesHuman-readable. Don't pattern-match.
error.statusonly when the error came from the APIThe HTTP status the server returned.
error.retryableyestrue if a retry has a reasonable chance of succeeding (rate limits, transient network failures).
error.hintoptionalOne-line suggestion. Surface this to your user.
error.doc_urlyesStable link to this page, anchored to the slug for code.
error.detailsoptionalCode-specific structured detail. Schema varies.

Exit codes

ExitWhen
0Success
1API error (4xx / 5xx other than auth or validation)
2Auth error — no token, invalid token, or insufficient scope
3Validation error — bad input or 422 from the server
4Network error — DNS, connection refused, timeout
5Internal CLI error — file an issue

Scripts should check the exit code first, then parse JSON. The exit code maps reliably to "should I retry?" / "did the user mess up?" / "did I mess up?" without parsing.

Canonical error codes

Each code has a stable #slug so doc_url always resolves. The slugs are the lowercase code with underscores replaced by hyphens.

no-token

Exit 2 · Not retryable. No token configured. Set PAPERMARK_TOKEN, run papermark login, or paste with papermark auth set --stdin. See Authentication.

auth-invalid

Exit 2 · API status 401 · Not retryable. A token was provided but the server rejected it. Either revoked, malformed, or for a different environment than --api-url points at.

forbidden

Exit 2 · API status 403 · Not retryable. The token is valid but lacks the scope this command needs. The error details will name the missing scope.

not-found

Exit 1 · API status 404 · Not retryable. The resource you addressed (document, link, dataroom, visitor) doesn't exist for this team. Confirm the ID and the team.

validation

Exit 3 · API status 422 · Not retryable. Input failed validation, either in the CLI before sending or by the server. details is a flattened map of field → error messages. Fix the input; don't retry.

rate-limited

Exit 1 · API status 429 · Retryable. Token's per-minute budget exceeded. The CLI itself retries with exponential backoff bounded by X-RateLimit-Reset; you'll only see this code if the retry budget is exhausted. See API Rate limits.

upstream-5xx

Exit 1 · API status 5xx · Retryable. The server had an internal error. The CLI retries automatically; you'll only see this code if the failure persists.

timeout

Exit 4 · Retryable. The HTTP request didn't get a response in the configured time budget. Could mean transient network trouble or that the API is overloaded. The CLI retries.

network-error

Exit 4 · Retryable. DNS failed, connection refused, TLS handshake failed. Check connectivity to api.papermark.com.

internal

Exit 5 · Not retryable. A bug inside the CLI itself. Please file an issue with the redacted command and the JSON output.

Stability promise

Within CONTRACT v1:

  • Codes are byte-stable. New codes may be added; existing codes won't be renamed.
  • Exit codes are stable.
  • Field names in the success / failure envelope are stable. New fields may be added.
  • Field shapes are stable. A field that was a string stays a string.

If we ever need to break any of the above, we'll bump to CONTRACT v2, ship papermark 2.0.0 with a --contract v1 opt-in for one minor release of the new major, then drop v1.

On this page