Skip to content

Command reference

Every papio command, generated directly from the binary. The --json flag is accepted globally, but it does not guarantee JSON output: init prints setup text, and mcp runs a server. Result-producing commands such as acquire, daemon status, and native-host status honor the flag. See the user guide for the operational workflow and the configuration reference for policy.

JSON output contract

Every list-shaped --json payload is a JSON object with exactly two keys, rows first: a named array and truncated (bool) — never a bare top-level array. An empty result is [], never null. truncated: true means the page filled its row cap (the default or --limit bound), so more rows may exist; it is not proof there are more — raise --limit or paginate to check.

This is the same envelope the MCP resources (papio://jobs and friends) already return, so one parser handles both surfaces:

{"jobs": [...], "truncated": false}

Commands that return a single structured record — papio jobs get, papio doctor, papio status, papio batch report, papio zotio plan, papio inbox — return that object directly; they are not list envelopes and carry no truncated key.

A failing command in --json mode prints one line on stderr, {"error":{"code":"not_found","message":"..."}}, and exits with the status below. code is the daemon's error code when the daemon refused the request, daemon_unreachable when no daemon answered, invalid_argument for a bad flag or argument count, and error otherwise; class, hint, and http_status appear when the daemon supplied them. Exit status: 0 on success, 2 for a usage error (a bad flag, argument count, or --config path; --json code invalid_argument), 3 when no daemon answered (daemon_unreachable), and 1 for every other failure, including an error the daemon returned. A command that already printed its structured result to stdout and then exits 1 (for example papio doctor with a failing check) keeps the plain papio: <message> stderr line instead, so read its stdout. Without --json, stderr is always the plain papio: <message> line.

Global flags

These flags are available on every command. --version is not one of them: it is a root-only flag, so run papio --version, not papio <subcommand> --version.

Flag Type Default Description
--config string config TOML path
--json bool false emit structured JSON

papio acquire

Submit one paper-acquisition request

papio acquire [identifier] [flags]
Flag Type Default Description
--access-mode string per-request access-mode override
--arxiv string arXiv ID
--author stringSlice [] author (repeatable)
--auto-import bool false plan and apply zotio import automatically when ready
--batch string submit works from a JSONL, RIS, BibTeX, CSL-JSON, MEDLINE/NBIB, or one-identifier-per-line file (or - for standard input)
--collection string target Zotero collection name (key when used with --from-zotio)
--consumer string name the submitting consumer, for per-consumer accounting on a shared daemon
--deny-source stringSlice [] deny this source (repeatable)
--desired-version string any published, accepted, preprint, or any
--doi string DOI
--force bool false create a fresh job even when this work is already in flight
--from-digest int64 0 queue pending entries from an alert watch; queued works are set to import into Zotero automatically when ready
--from-zotio bool false queue zotio items missing an attached PDF
--include-owned bool false with --batch, submit works already carrying a PDF in zotio
--isbn string ISBN
--keys stringArray [] digest work key to queue (repeatable)
--label string query context; also the default target collection when --collection is unset
--limit int 25 maximum zotio items to queue
--max-cost float64 0 maximum paid-source cost in USD
--openalex string OpenAlex work ID
--pmid string PubMed ID
--request-id string convergence key: resubmitting it returns the same still-live job; once that job finishes, the same key queues a fresh attempt
--resolver string named institutional OpenURL resolver profile
--source stringSlice [] allow only this source (repeatable)
--title string work title
--wait bool false wait for a terminal or human-action state
--year int 0 publication year
--zotio-item-key string existing Zotero item key

papio actions

Inspect required human actions

papio actions

papio actions dismiss

Close a stale human action; cancels its parked job when it was the last open action

Close a stale human action.

An advisory on a terminal job has no other way out: cancel refuses a terminal job, resolve is identity-review only, and the startup sweep deliberately leaves informational advisories alone so a real trace survives. Without this, retiring one meant editing the database or retrying the job purely to cancel it again.

When the dismissed action is the job's last open action and the job is parked on it (awaiting_human on an openurl_handoff, manual_download, openurl_available, or document_delivery action; needs_review on a verify_identity or unsafe_pdf action), dismissing it also cancels the job. Otherwise the job is left untouched.

--revision guards against dismissing an action that changed after you listed it; take it from the revision column of papio actions list.

papio actions dismiss <action-id> [flags]
Flag Type Default Description
--revision int64 0 revision the action had when you listed it

papio actions list

List open human actions

List open human actions.

An action queued long enough to look abandoned is reported stale — age_seconds and stale in --json, a trailing marker in the text listing — against the configured actions.stale_after_seconds. Staleness is a label and nothing else: no handoff is ever cancelled on a timer, because giving up on an acquisition is your call.

papio actions list [flags]
Flag Type Default Description
--all bool false include resolved actions
--consumer string only actions whose job was submitted under this consumer name
--limit int 100 maximum rows (1-500)

papio actions open

Open the current browser handoff queue

Open the current browser handoff queue.

With no selector this opens the whole openable queue, newest first. --job or --action opens exactly one row instead, for a caller that ranked the queue itself and wants the row it chose. A job holding several open actions is refused with their ids rather than resolved by picking one, and a selector naming no open action is an error: falling back to the head of the queue would open somebody else's handoff and report success.

A manual download opens on your library's route, with one exception. When an open-access route left the download, or your library has already reported no entitlement for the paper, that route cannot serve it: papio sends the job back to resolving instead, where it looks up the open-access route again and offers it in the browser. No library link opens. --dry-run prints each such job with "would return to resolving".

The selector is for choosing a row, not for iterating the queue. A background caller that loops it over every row has built the autonomous drain ADR-0009 does not ratify: your browser is one serial surface, and filling it with tabs nobody asked for is not acquisition progress.

papio actions open [flags]
Flag Type Default Description
--action int64 0 open only this action id
--dry-run bool false print URLs, and the jobs sent back to resolving, without opening anything
--job string open only this job's open action
--limit int 0 maximum actions to open (default all)

papio actions resolve

Accept or reject a parked identity or unsafe-PDF review

Accept or reject a parked identity or unsafe-PDF review.

The verdict applies only to the review you inspected. --revision is required for both verdicts, and --accept also needs --sha256, the quarantined file's digest; take the revision from the revision column of papio actions list and the digest from papio actions list --json (quarantine_sha256). If the action or its file changed since you listed it, nothing is applied and the command exits nonzero: list the action again and re-inspect the file before deciding.

--reject cancels the job for an identity review; for an unsafe PDF it sends the job back to awaiting_human for a manual download.

papio actions resolve <action-id> [flags]
Flag Type Default Description
--accept bool false accept the identity review
--reject bool false reject the identity review
--revision int64 0 revision the action had when you listed it
--sha256 string quarantine_sha256 of the file you inspected (required with --accept)

papio actions retry-publisher

Retry a failed route through the DOI or an upgraded institution adapter

Retry a failed browser route through the paper's DOI in your browser.

If the DOI retry has already failed, this command re-offers the original institutional route only when the refusing adapter has since been upgraded. Use the action id and revision from the revision column of 'papio actions list'. The failed action and its evidence remain in the job history. Each route can be retried once. Pending sign-ins, challenges, terms, downloads, and unresolved browser effects must be handled first. Neither retry establishes entitlement.

papio actions retry-publisher <action-id> [flags]
Flag Type Default Description
--revision int64 0 revision the failed action had when you listed it

papio activity

Show recent daemon activity

papio activity [flags]
Flag Type Default Description
--before-seq int64 0 show only events older than this sequence number (the seq of the last row of the previous page); 0 starts at the newest
--job string filter activity to one job ID
--limit int 30 maximum activity rows (1-200)

papio adapter

Inspect provider and adapter interactions

papio adapter

papio adapter capture

Capture a provider page through the connected browser

papio adapter capture <url> [flags]
Flag Type Default Description
--provider string provider adapter id: lowercase, such as wiley or sage
--scenario string fixture scenario
--settle-ms int64 0 milliseconds to settle after page load (0-10000)

papio adapter captures

List stored diagnostic page captures

papio adapter captures

papio adapter captures purge

Remove stored diagnostic page captures

Remove stored diagnostic page captures for one host (--host) or for every host (--all). One of the two is required: a bare purge is refused.

The removal includes captures pinned as incident evidence (the first decisive and latest capture of an open incident) and cannot be undone. Run with --dry-run first to see how many captures would be removed.

papio adapter captures purge [flags]
Flag Type Default Description
--all bool false purge captures for every host
--dry-run bool false count the captures that would be removed without removing anything
--host string purge captures for one host

papio adapter diagnose

Build a sanitized support report for a job

papio adapter diagnose <job-id>

papio adapter repair

Scaffold a reviewed adapter repair workspace

papio adapter repair <capture-id-or-path> [flags]
Flag Type Default Description
--provider string provider adapter id (must match daemon capture metadata)
--recovery-job string job that recorded this capture, failed declaratively, then reached ready with a validated PDF
--scenario string fixture scenario (must match daemon capture metadata)

papio artifacts

Inspect validated immutable artifacts

papio artifacts

papio artifacts get

Show a validated artifact

papio artifacts get <job-id-or-sha256> [flags]
Flag Type Default Description
--sha256 bool false interpret argument as an artifact hash

papio artifacts locate

Print where one job's validated artifact bytes live

papio artifacts locate <job-id>

papio artifacts text

Print the extracted text of a validated artifact, one page range at a time

Print the text of a validated artifact, extracted by the daemon's bounded pdftotext (the same tool, timeout and process-tree kill validation uses). No OCR runs: ocr_used is always false, so a scanned PDF yields little or no text.

Only the artifact of a job in state ready or imported is served. A job in any other state, a quarantined file, a hash held only by jobs that are not ready or imported, and an unknown hash are each refused with a distinct error.

One read returns at most 131072 bytes (128 KiB) of text, a limit chosen so the JSON-escaped result always fits the daemon's 1 MiB result cap. --max-bytes may lower that limit, never raise it. Page ranges are the paging mechanism: when truncated is true, read on from last_page with --pages -.

--pages 2-3 pages 2 and 3 --pages 5 page 5 only --sha256 treat the argument as an artifact hash, not a job id

--json prints {text, first_page, last_page, pages_total, chars, truncated, ocr_used}. Without --json the text is printed with terminal control characters removed (the text comes from an untrusted file); --json keeps it byte-exact.

papio artifacts text <job-id-or-sha256> [flags]
Flag Type Default Description
--max-bytes int 131072 lower the per-read byte limit (never above 131072)
--pages string page range to read, a-b or a (default: the whole document, up to the byte limit)
--sha256 bool false interpret argument as an artifact hash

papio artifacts validation

Print the full validation report for every candidate a job validated

Print the full validation report for every candidate a job validated.

artifacts get returns the shared, content-addressed artifact row — which is all it can return, because an artifact belongs to every job that obtained the same bytes (ADR-0007). This is the per-job evidence: the payload gate, the structural parse, text extraction, and the identity decision, each with the reasons and capability evidence behind it, for the candidates that were kept AND the ones that were rejected.

Each report is a versioned document (validation-report/1). A job validated before this evidence was recorded lists no reports; that is an absence, not an empty verdict.

papio artifacts validation <job-id>

papio batch

Inspect persisted acquisition batches

papio batch

papio batch report

Join a batch manifest with live acquisition outcomes

papio batch report <batch-id|latest> [flags]
Flag Type Default Description
--markdown bool false emit an agent-ready Markdown digest

papio bench

Run the hermetic comparative acquisition benchmark over a cohort file

papio bench [flags]
Flag Type Default Description
--cohort string path to a papio-bench-cohort/1 document
--fixtures string fixture directory (default: the cohort file's sibling "fixtures" directory)

papio browser

Inspect and switch connected browser sessions

papio browser

papio browser permit

Recover daemon-owned browser effect permits

papio browser permit

papio browser permit resolve

Release one unknown-completion browser effect permit

Release one exact unknown-completion effect permit after an operator has independently resolved whether its browser effect completed. This is break-glass recovery; it never releases a held permit.

papio browser permit resolve <permit-id> [flags]
Flag Type Default Description
--reason string operator reason recorded in the durable audit event

papio browser reload

Reload the connected development-mode extension from disk

Reload a development-mode extension from disk. --session selects a connected browser by unambiguous session-id prefix, promoting a pending session first. Without it, reload the current holder. The extension refuses reload unless chrome.management.getSelf() reports installType "development".

papio browser reload [flags]
Flag Type Default Description
--session string reload this browser session (unambiguous id prefix); promote it if pending
--timeout duration 15s how long to wait for the reloaded extension to reconnect (0 waits not at all)

papio browser sessions

List currently connected browser sessions

papio browser sessions

papio browser use

Give one browser session the papio offer/handoff flow

papio browser use [session-id] [flags]
Flag Type Default Description
--latest bool false switch to the most recently active pending session

papio bundle

Read and export validated acquisition bundles

papio bundle

papio bundle document

Print the acquisition bundle without writing it anywhere

papio bundle document <job-id>

papio bundle export

Export an idempotent bundle directory

papio bundle export <job-id> [flags]
Flag Type Default Description
-o, --output string destination directory

papio campaign

Stage a selected citation export in bounded acquisition chunks

papio campaign

papio campaign import

Preview and persist up to 200 source records without submitting jobs

papio campaign import <file> [flags]
Flag Type Default Description
--collection string destination collection; automatic Zotero import stays off
--resolver string institution resolver profile

papio campaign list

List staged campaigns: id, creation time, works, acknowledged chunks and paused state

papio campaign list

papio campaign pause

Prevent further staged submission

papio campaign pause <id>

papio campaign preview

Classify all campaign works without submitting

papio campaign preview <id>

papio campaign report

Return one outcome for every original source record

papio campaign report <id>

papio campaign resume

Allow staged submission without submitting yet

papio campaign resume <id>

papio campaign run

Submit at most one chunk within the 50-active-work window

papio campaign run <id>

papio config

Manage papio configuration

papio config

papio config acknowledge-closure

Reopen paid egress for a source that closed on price or balance drift (requires --confirm)

A source's paid egress closes, and stays closed with no timed reopen, when the provider's prices stop matching the schedule papio committed against or when its prepaid balance falls below the starting observation. 'papio doctor' names the closed source and the reason.

This command acknowledges the closure after you have checked the provider's account, and reopens egress. The next response from the provider sets the new balance baseline. Without --confirm nothing changes. It exits nonzero when the source was not closed.

papio config acknowledge-closure SOURCE [flags]
Flag Type Default Description
--confirm bool false reopen paid egress for the source

papio config agent

Configure optional article-agent decisions

papio config agent

papio config agent remove

Disable the configured agent while preserving stored credentials

papio config agent remove

papio config agent set

Enable TypeSafe/Jev with a key saved in the OS credential store

Enable cloud article decisions for this configuration profile. This sends article DOIs, bounded titles and sanitized control descriptions to TypeSafe. The key is stored as a shared-service typed credential with an explicit reference. Input is hidden; use --key-stdin for a secret-manager pipe. The running daemon keeps the old setting until it is stopped: run 'papio daemon stop' after changing it, and the next papio command starts the daemon with it.

papio config agent set [flags]
Flag Type Default Description
--key-stdin bool false read the API key from standard input instead of a hidden terminal prompt

papio config agent status

Show agent configuration without revealing credentials

papio config agent status

papio config credentials

Manage integration credentials in the OS store or environment

papio config credentials

papio config credentials bind

Reuse an existing typed credential for this configuration

papio config credentials bind TARGET REFERENCE

papio config credentials delete

Delete a stored record without changing configurations that reference it (requires --yes)

Delete one stored credential record. Deletion cannot be undone, and a record can be shared: another configuration bound to it keeps a reference that no longer resolves, and its integration fails after the next restart. Papio cannot see other configurations. It refuses to delete a record this configuration binds (detach it first), and without --yes it only describes the deletion and exits nonzero.

papio config credentials delete REFERENCE [flags]
Flag Type Default Description
--yes bool false delete the record; without it the command only describes the deletion

papio config credentials detach

Remove a configuration binding while preserving the stored record

papio config credentials detach TARGET

papio config credentials migrate

Move this configuration's legacy secrets into verified OS records

Migrate supported literal credentials and this profile's legacy TypeSafe key. New records are verified before one guarded config update. Existing vault entries are retained. Interrupted operations report staged references for inspection or explicit deletion. The previous config is saved to config.toml.bak (mode 0600) and may still hold the literal secrets; delete it once you have checked the result. An active legacy TypeSafe environment override must be removed before migration.

papio config credentials migrate

papio config credentials set

Save a new credential and bind this configuration to it

Create a fresh OS credential record for one integration. Supply a single API key at the hidden prompt or with --key-stdin. For sources.openaire and notify.webhook, use --key-stdin with a version-1 typed JSON credential record. TypeSafe setup enrolls this profile in cloud article decisions. The running daemon keeps the old credential until it is stopped: run 'papio daemon stop' after changes, and the next papio command starts the daemon with them.

papio config credentials set TARGET [flags]
Flag Type Default Description
--key-stdin bool false read a key or typed JSON record from standard input

papio config credentials status

Show selected credential sources without revealing values

papio config credentials status [TARGET]

papio config init

Write explicit first-run configuration

Write a new configuration with defaults and the given access mode. With --force it replaces an existing file: every other setting, including data_dir, institutions, sources, hooks and credential bindings, is reset to defaults. The previous file is saved to config.toml.bak (mode 0600, replacing any older backup); it may hold plaintext secrets. To change only the access mode, use 'papio config set-access-mode'.

papio config init [flags]
Flag Type Default Description
--access-mode string required: conservative, assisted, or delegated
--data-dir string artifact and database directory
--email string contact email for polite APIs
--force bool false replace an existing config and reset every other setting

papio config set-access-mode

Change access_mode in the existing config and keep every other setting

Set access_mode to conservative, assisted, or delegated in the existing configuration. Every other setting is kept. A running daemon keeps its old mode until it restarts.

papio config set-access-mode MODE

papio daemon

Run or control the local acquisition daemon

papio daemon
Flag Type Default Description
--socket string Unix socket path

papio daemon status

Check the running daemon without autostarting one

papio daemon status

papio daemon stop

Stop the running daemon without autostarting one

papio daemon stop

papio delivery

Manage document-delivery and ILL requests

papio delivery

papio delivery cancel

Cancel a document-delivery request that has not reached the provider

Cancel a document-delivery request that has not reached the provider.

papio cancels a request locally while it is still offered or declined. It cannot cancel a request that is already live at the provider: no provider adapter supports API cancellation, so cancel that one directly with the institution. For a request in unknown_outcome, check with the provider and then use 'papio delivery confirm-absent'. A refused cancellation exits nonzero.

papio delivery cancel <job-id>

papio delivery confirm-absent

Confirm no request exists at the provider, cancel the stale row, and reopen reconciliation for a deliberate decision (v1 never auto-resubmits)

papio delivery confirm-absent <job-id>

papio delivery confirm-exists

Confirm a lodged request exists at the provider and resume polling

papio delivery confirm-exists <job-id> <provider-reference>

papio delivery get

Show a job's document-delivery request and compiled gate

papio delivery get <job-id>

papio delivery history

Show a delivery request's history for reconciliation (Decision 4's open_request_history)

papio delivery history <job-id>

papio delivery resume

Clear a live delivery request's poll-failure bookkeeping (e.g. a contract-drift park) so the next poll is no longer a no-op

papio delivery resume <request-id>

papio delivery submit

Route a job to document delivery; may place a real ILL request with the provider (requires --confirm)

Route a job to document delivery.

This runs the document-delivery Branch/gate decision and acts on it. When the institution's gate allows automatic submission, papio places a real request with the provider — which can count against a request allowance or cost the institution money, and which papio cannot cancel through the provider. Otherwise it opens a prefill or reconciliation action.

Without --confirm nothing is submitted: the command reports what --confirm would do for this job (a real provider request, a prefill action, or the handling of an existing request) and exits nonzero.

papio delivery submit <job-id> [flags]
Flag Type Default Description
--confirm bool false run the gate and, when it allows, place the provider request

papio doctor

Check acquisition readiness and local integrations

papio doctor

papio drive

Inspect and pause the paced drive of parked handoffs

The paced drive opens parked handoffs for you, one at a time, oldest first, through the same path as 'papio actions open'. It is off unless [drive] enabled = true in the config, and it waits whenever the browser is busy, a sign-in is open, a provider is refusing this browser, or the hourly bound is spent. A sign-in nobody completes pauses it and notifies you.

papio drive

papio drive pause

Stop paced opens until 'papio drive resume'

papio drive pause

papio drive resume

Let the paced drive open handoffs again

papio drive resume

papio drive status

Show whether the paced drive would open a handoff, and what blocks it

papio drive status

papio export

Export normalized citation records (CSL-JSON, RIS, BibTeX)

papio export
Flag Type Default Description
--force bool false replace the -o file when it already exists (without it, an existing file is refused)
--format string citation format: csl-json, ris, or bibtex (default csl-json, inferred from -o's extension)
--include-duplicates bool false keep records whose canonical identity repeats instead of collapsing them
-o, --output string write citations to this file instead of stdout (required with --json)

papio export batch

Export every work in the batch manifest in manifest order, including skipped and unavailable works

papio export batch <batch-id>

papio export campaign

Export every distinct work staged in a campaign (read-only: no daemon call); unparseable source records are skipped and counted

papio export campaign <campaign-id>

papio export job

Export the named jobs in argument order (any state: citation metadata stays useful when retrieval failed)

papio export job <job-id>...

papio export ledger

Export one record per canonical work (validated acquisitions by default)

papio export ledger [flags]
Flag Type Default Description
--consumer string only works submitted by this consumer
--since string only works submitted after this instant (RFC3339) or within this duration (e.g. 24h, 7d)
--state string acquired which works to export: acquired (ready or imported; validated acquisitions), ready (not yet imported) or any (every job)

Export the rows of a saved search snapshot (read-only: no daemon call)

papio export search <snapshot-file> [--keys k1,k2] [flags]
Flag Type Default Description
--keys stringSlice [] export only these snapshot row keys (comma-separated; an unknown key is an error)

papio export watch

Export a watch's pending digest entries

papio export watch <watch-id>

papio failures

Aggregate unavailable and parked acquisition reasons

papio failures [flags]
Flag Type Default Description
--by-provider bool false group by provider host/source instead of reason
--limit int 20 maximum aggregate rows (1-200)

papio grabs

Manage captured PDF grabs

papio grabs

papio grabs binds

List captures papio filed automatically, without asking

List captures papio bound to a pending job on its own, newest first.

papio only does this when a settled, DOI-less capture qualifies exactly one pending job; everything else still parks for a human. Because there is no unbind command, this listing — the rule version, how many candidates were on the table, and the evidence that made one of them the winner — is the only way to check an automatic filing after the fact.

One page holds at most 200 binds. When more exist, the listing ends with the command for the next page: --before with the last grab id shown.

papio grabs binds [flags]
Flag Type Default Description
--before string list only binds older than this grab id (the last grab of the previous page)
--limit int 50 maximum autonomous binds to list (default 50, max 200)

papio grabs confirm

File a parked capture against the job you picked

Bind a parked capture to a specific pending job chosen by a human — typically the top (or any) row of papio grabs suggest's ranking.

papio still refuses the pick if the document's own front matter names a different paper: extracted identity outranks a human pick, the same rule autonomous binding already applies to itself. A refusal changes nothing — no job is created and the capture stays parked exactly as it was before.

papio grabs confirm <grab-id> [flags]
Flag Type Default Description
--job string pending job id to file this capture against

papio grabs identify

Bind an operator-supplied identifier to a captured PDF grab

Bind an operator-supplied identifier to a captured PDF grab that parked without one, creating or joining the job for that work.

When a ready job already holds the identifier, the outcome is already_owned and the capture is kept, still parked: nothing checks the typed identifier against the file, so it may be a different paper or version. Discard it with papio inbox decide pdf_grab:<grab-id> --op dismiss --delete-grab.

papio grabs identify <grab-id> [flags]
Flag Type Default Description
--arxiv string identify by arXiv ID
--doi string identify by DOI
--pmid string identify by PubMed ID

papio grabs suggest

Rank pending jobs against a parked capture: which paper is this?

Rank the pending jobs that best match a capture which parked instead of binding on its own, most-likely first, with the evidence behind each ranking. Nothing is filed by running this — it only orders the candidates a human would otherwise have to hunt through by hand; pick one and run papio grabs confirm to actually file it.

If the captured file states its own DOI, PMID, or arXiv ID in its front matter, that identifier is printed first: papio grabs identify with that value is faster and more certain than picking from the ranked list below it.

papio grabs suggest <grab-id> [flags]
Flag Type Default Description
--limit int 5 maximum ranked suggestions to return (default 5, max 25)

papio inbox

Show the triage inbox

papio inbox [flags]
Flag Type Default Description
--cursor string continue from the cursor printed after the previous page
--limit int 0 maximum items (default 50, maximum 100)

papio inbox counts

Show complete triage inbox counts

papio inbox counts

papio inbox decide

Acquire or dismiss one triage inbox item

Acquire or dismiss one triage inbox item. is the first column of papio inbox (also id in papio inbox --json).

Dismissing a captured PDF grab (an item id starting with "pdf_grab:") permanently deletes the captured file and its grab record; papio grabs suggest and papio grabs identify cannot recover it afterwards. That dismissal is refused unless --delete-grab confirms it.

A decision that did not apply (conflict or invalid) exits nonzero after printing its outcome.

papio inbox decide <item-id> [flags]
Flag Type Default Description
--delete-grab bool false confirm that dismissing a captured PDF grab permanently deletes its file
--op string acquire or dismiss
--watch-scope string all for dismiss: all, or a comma-separated list of watch IDs

papio init

Set up papio for a first run

papio init [flags]
Flag Type Default Description
--attachment-mode string zotio attachment mode: stored or linked-file
--check-updates bool true check for papio and zotio updates once a day via GitHub releases (sends nothing else)
--email string contact email for polite API pools
--extension-id string Chrome extension ID allowed to reach the native host, or an unpacked extension folder path (papio computes its ID)
--firefox-extension-id string Firefox add-on ID allowed to reach the native host
--institution-url string library discovery or resolver URL; papio derives the OpenURL base
--libkey-library-id string numeric Third Iron library id, or a BrowZine/LibKey.io URL containing /libraries/; enables LibKey link routing (blank disables)
--non-interactive bool false do not prompt; retain existing values unless a flag overrides them
--openurl-base string institution OpenURL resolver base URL
--proquest-account-id string ProQuest account id, or a ProQuest URL containing accountid=
--shibboleth-entity-id string Shibboleth IdP entityID for federated login-routing
--skip-browser bool false skip Chrome extension and native-host setup
--zotio-path string zotio executable path

papio jobs

Inspect and control acquisition jobs

papio jobs

papio jobs add-component

Add a supplement or appendix PDF from any path to a job

Add a supplement or appendix to a job that already holds its main PDF (ready or imported). The file can be anywhere on this computer. papio copies it into its data directory and runs the same payload and structure checks as a main PDF; a supplement is not checked against the requested work. Your original file is not changed.

Use supply-pdf for a job's main file.

papio jobs add-component <job-id> <path> [flags]
Flag Type Default Description
--role string component role: supplement or appendix

papio jobs archive

Archive a validated acquisition without deleting its artifact

papio jobs archive <job-id> [flags]
Flag Type Default Description
--confirm bool false confirm the archive decision; do not delete retained artifacts

papio jobs cancel

Cancel a nonterminal job

papio jobs cancel <job-id>

papio jobs diagnose

Explain why one job needs attention and what can happen next

papio jobs diagnose <job-id>

papio jobs disposition

Inspect acquisition disposition and retained artifact

papio jobs disposition <job-id>

papio jobs failures

Group acquisition jobs that need attention

Group acquisition jobs that need attention.

Incident fingerprints omit raw hosts and identifiers and are keyed per installation; local output intentionally includes bounded safety_domain and registrable host_family labels for diagnosis.

papio jobs failures [flags]
Flag Type Default Description
--limit int 50 maximum groups (1-200)
--since string include jobs updated since an RFC3339 timestamp or within this duration (e.g. 24h, 7d)

papio jobs filing

Inspect and retry durable managed folder filing

papio jobs filing

papio jobs filing inspect

Inspect managed destination receipts and retry state

papio jobs filing inspect <job-id> [flags]
Flag Type Default Description
--limit int 100 maximum receipts (1-500)

papio jobs filing list

Inspect managed destination receipts and retry state

papio jobs filing list [flags]
Flag Type Default Description
--limit int 100 maximum receipts (1-500)

papio jobs filing retry

Safely replay a journaled managed folder destination

papio jobs filing retry <job-id> [flags]
Flag Type Default Description
--destination string journaled folder destination; default is the configured folder

papio jobs get

Show one job with events and actions

papio jobs get <job-id> [flags]
Flag Type Default Description
--wait bool false wait for completion or human action

papio jobs incidents

Group decisive provider incidents

Group decisive provider incidents by keyed failure shape.

The fingerprint omits raw hosts and identifiers and is keyed per installation; local output intentionally includes bounded safety_domain and registrable host_family labels for diagnosis.

papio jobs incidents [flags]
Flag Type Default Description
--limit int 50 maximum groups (1-200)
--since string include incidents recorded since an RFC3339 timestamp or within this duration (e.g. 24h, 7d)

papio jobs list

List jobs

papio jobs list [flags]
Flag Type Default Description
--consumer string only jobs submitted under this consumer name
--limit int 100 maximum rows (1-500)
--state string only jobs in this state: queued, resolving, fetching, validating, ready, imported, awaiting_human, retry_wait, needs_review, unavailable, failed, cancelled

papio jobs receipt

Show the outcome and component index for one job

papio jobs receipt <job-id>

papio jobs redrive

Replace a spent manual download, open-access handoff, or terms park with an institutional handoff

Replace a parked manual download, an open-access browser handoff whose URL answered HTML, or an open terms_acceptance_required action with no live browser claim, with a fresh institutional handoff.

An unavailable job whose terminal reason is browser_rejected is also accepted with --revision 0: that reason came from an empty browser job_reject, which says nothing about the paper, and redrive returns the job to awaiting_human with a fresh institutional handoff.

A needs_review job whose one open manual download asks you to remove an adopted file that failed validation is accepted once that file is gone from the job's adoption directory. Redrive returns it to awaiting_human with a fresh institutional handoff; while the file remains, it refuses.

Two parks go back to resolving instead, with no new action: a manual download left by an open-access browser route, where papio looks up that route again, and any spent route of a job whose institution has already reported no entitlement. Resolving offers a live open-access handoff when one remains, an untried institutional handoff next, and otherwise settles the job.

Redrive accepts nothing on the provider: the extension's own terms consent setting decides again when the handoff is driven, and without consent the job parks on terms again.

Use the revision column of papio actions list. For a job whose action is already resolved and has no open action, use --revision 0. This runs once per observed browser outcome. It does not open a tab.

papio jobs redrive <job-id> [flags]
Flag Type Default Description
--revision int64 0 revision of the open manual download, open-access handoff, or terms action; 0 if no action is open

papio jobs refile

Run the configured on-ready filing hook again

Run the [hooks] on_ready command from your configuration again for a ready or imported job. The command runs through your shell with the daemon's environment, and whatever it files is written to your library, so check the job id first.

--dry-run prints the command that would run, and the refusals that would stop it, without running anything.

papio jobs refile <job-id> [flags]
Flag Type Default Description
--dry-run bool false print the hook command that would run, without running it

papio jobs repair-awaiting-human

Return an orphaned awaiting-human job with no open actions to resolving

papio jobs repair-awaiting-human <job-id>

papio jobs restore

Restore an archived acquisition to the actionable ready view

papio jobs restore <job-id>

papio jobs retry

Explicitly retry a failed, unavailable, or retry-wait job

papio jobs retry <job-id>

papio jobs show

Show one job with events and actions

papio jobs show <job-id> [flags]
Flag Type Default Description
--wait bool false wait for completion or human action

papio jobs supply-pdf

Supply a local PDF as a job's main file

Supply a PDF you already have — an email attachment, an interlibrary loan copy, or an earlier download — as the main file of an existing job. papio copies the file into its data directory and runs the same checks as a browser download: the PDF must be readable and must be the requested work. A PDF of a different work goes to identity review or is rejected; it never becomes ready unchecked. Your original file is not changed.

The job must still be open: queued, resolving, fetching, waiting to retry (retry_wait), or awaiting a human download. A finished job (ready, imported, unavailable, failed, or cancelled) cannot take a PDF: submit the work again with papio acquire, then supply the PDF to the new job id.

Use add-component for supplements and appendices.

papio jobs supply-pdf <job-id> <path>

papio jobs unfiled

List ready jobs whose on-ready filing is missing or failed

papio jobs unfiled [flags]
Flag Type Default Description
--filter string all filing filter: failed, missing, or all
--limit int 100 maximum rows (1-500)

papio mcp

Serve papio tools and resources over MCP stdio

papio mcp

papio native-host

Manage browser native-messaging host registration

papio native-host

papio native-host install

Register native-messaging host manifests and the host executable

papio native-host install [flags]
Flag Type Default Description
--firefox-manifest-dir string override the Firefox native-messaging manifest directory
--manifest-dir string override the Chrome native-messaging manifest directory

papio native-host status

Report native-messaging host registration state

papio native-host status [flags]
Flag Type Default Description
--firefox-manifest-dir string override the Firefox native-messaging manifest directory
--manifest-dir string override the Chrome native-messaging manifest directory

papio native-host uninstall

Remove native-messaging host manifests and the host executable

Remove the native-messaging manifests of every known browser (Chrome, Edge, Vivaldi, Brave, Opera, Chromium, Firefox) and the shared host executable. With --manifest-dir or --firefox-manifest-dir, act only on the named directories (Chrome manifest, Firefox manifest) and keep the host executable unless --remove-host is given.

papio native-host uninstall [flags]
Flag Type Default Description
--dry-run bool false list what would be removed without removing it
--firefox-manifest-dir string remove only the Firefox manifest in this directory; other browsers and the host executable stay
--manifest-dir string remove only the Chrome manifest in this directory; other browsers and the host executable stay
--remove-host bool false with a directory override, also remove the shared host executable that every browser uses

papio notify

Inspect and test notification routing

papio notify

papio notify preview

Preview notification copy without sending

papio notify preview <category> [flags]
Flag Type Default Description
--count int 1 number of events represented in the preview

papio notify show

Show effective notification routing

papio notify show

papio notify test

Send one local or webhook notification test

Send one test notification for a category. By default the test goes to the local desktop channel. With --webhook it is posted once to the configured webhook in its configured notify.webhook_format, bypasses the ledger, and reports whether the endpoint answered with a 2xx status.

papio notify test <category> [flags]
Flag Type Default Description
--webhook bool false send the test through the configured webhook instead of the desktop

papio pulse

Show the daemon's current work pulse

papio pulse

Search configured discovery backends for scholarly works

papio search [query] [flags]
Flag Type Default Description
--cited-by string DOI to find papers it cites (backward references; OpenAlex cited_by: filter)
--cites string DOI to find papers citing it (forward citations; OpenAlex cites: filter)
--continuation string resume a new-only search with its exact query and filters
--limit int 20 maximum results (1-50)
--new-only bool false page until the requested unowned count or a disclosed scan budget
--oa-only bool false return only open-access works
--related-to string DOI to find OpenAlex-related papers (related_to: filter)
--source string discovery backend: arxiv, openalex, or semanticscholar (default: all configured)
--year-from int 0 minimum publication year
--year-to int 0 maximum publication year

papio search acquire

Preview selected search keys; submit only with --confirm

papio search acquire <snapshot> [flags]
Flag Type Default Description
--collection string destination collection
--confirm bool false submit exactly the selected works after current ownership classification
--keys stringSlice [] comma-separated exact keys from the search snapshot
--label string search selection batch label
--resolver string institution resolver profile

papio search save

Save a bounded search result set for explicit selection

papio search save <snapshot> <query> [flags]
Flag Type Default Description
--limit int 20 maximum selected search candidates (1-50)
--new-only bool false fill the bounded snapshot with unowned results
--oa-only bool false open-access results only
--source string configured discovery backend
--year-from int 0 minimum publication year
--year-to int 0 maximum publication year

papio stats

Show lifetime acquisition totals by access basis

papio stats

papio stats page-bulk

Show page-bulk scan/submit funnel and identifier yield

papio stats page-bulk

papio stats producers

Show who produced each acquired artifact and how many needed a person

papio stats producers [flags]
Flag Type Default Description
--since string 24h count promotions since this RFC3339 instant or within this duration (e.g. 24h, 7d)
--until string count promotions before this RFC3339 instant (default now)

papio status

Show active and recent acquisition jobs

papio status [flags]
Flag Type Default Description
--follow bool false refresh every 2 seconds

papio version

Print version information

papio version

papio watch

Manage scheduled discovery watchlists

papio watch

papio watch add

Add a scheduled discovery watch

Add a scheduled discovery watch. Backfill watches take no query. Alert-mode discovery watches report new works without acquiring them.

By default (--mode acquire, --cadence daily) a discovery watch runs on its own schedule and submits up to --limit-per-run new works each run, and every job it submits asks for automatic Zotero import once it is ready, whatever zotio.auto_import says (zotio.auto_import_paused still pauses it). Use --mode alert to only report new works to the watch digest and acquire them on demand.

papio watch add [query] [flags]
Flag Type Default Description
--cadence string daily daily, weekly, or Nh
--cited-by string DOI to find papers it cites (backward references; OpenAlex cited_by: filter); replaces the query and excludes --cites
--cites string DOI to find papers citing it (forward citations; OpenAlex cites: filter); replaces the query and excludes --cited-by
--collection string zotio collection for queued papers
--kind string discovery watch kind: discovery or backfill
--label string human label (defaults to query)
--limit-per-run int 10 maximum new papers queued per run (1-50)
--mode string acquire discovery mode: acquire or alert
--oa-only bool false return only open-access works
--year-from int 0 minimum publication year
--year-to int 0 maximum publication year

papio watch backfill

Manage explicit non-Zotero library backfill

papio watch backfill

papio watch backfill add

Schedule missing PDFs from a declared record_present source

papio watch backfill add [flags]
Flag Type Default Description
--cadence string daily daily, weekly, or Nh
--label string human label
--limit-per-run int 10 maximum new papers per run (1-50)
--source string configured record_present library source name (required)

papio watch digest

Show recently reported works from an alert watch

papio watch digest <id> [flags]
Flag Type Default Description
--limit int 100 maximum digest entries to show (1-500)

papio watch digest clear

Clear pending works from an alert watch digest

Discard every pending work in an alert watch digest, including works papio watch digest did not show (it lists 100 by default). A cleared work is never reported again. Clearing requires --all; --dry-run counts the pending works without clearing them. To discard single works instead, use papio inbox decide <item-id> --op dismiss.

papio watch digest clear <id> [flags]
Flag Type Default Description
--all bool false confirm clearing every pending work, including works the digest view did not show
--dry-run bool false count the pending works without clearing them

papio watch edit

Change operational watch settings without resetting history

papio watch edit <id> [flags]
Flag Type Default Description
--cadence string daily, weekly, or Nh
--collection string destination collection
--label string human label
--limit-per-run int 0 maximum papers per run (1-50)
--oa-only bool false return only open-access works
--year-from int 0 minimum publication year (0 clears)
--year-to int 0 maximum publication year (0 clears)

papio watch list

List scheduled discovery watches

papio watch list

papio watch publication

Monitor acquired preprints without replacing their PDFs

papio watch publication

papio watch publication acquire

Explicitly acquire a published manifestation and keep the original

papio watch publication acquire <notice-id> [flags]
Flag Type Default Description
--confirm bool false approve acquisition of this exact published manifestation

papio watch publication add

Opt in an acquired preprint or accepted manuscript

papio watch publication add <job-id> [flags]
Flag Type Default Description
--cadence string weekly daily, weekly, or Nh

papio watch publication list

List publication watches

papio watch publication list

papio watch publication notices

List verified publication notices

papio watch publication notices <id>

papio watch publication pause

Stop scheduled checks and keep notice history

papio watch publication pause <id>

papio watch publication run

Check typed publication relations now

papio watch publication run <id>

papio watch remove

Remove a scheduled discovery watch

Remove a scheduled discovery watch. Jobs and Zotero items earlier runs created stay. The watch's digest is deleted with it, so removing a watch that still has pending (unreviewed) digest works is refused unless --discard-digest confirms that those works are discarded too.

papio watch remove <id> [flags]
Flag Type Default Description
--discard-digest bool false remove the watch even though pending digest works are deleted with it

papio watch resume

Re-enable a watch that repeated failures disabled

Re-enable a watch that five consecutive failures disabled, keeping its id, query, and digest history.

Fix the failing source first, then force a run with papio watch run <id>. Resume refuses until a run has succeeded since the watch was disabled.

papio watch resume <id>

papio watch run

Force-run a scheduled discovery watch now

papio watch run <id>

papio zotio

Preview and apply Zotero integration through zotio

papio zotio

papio zotio apply

Apply one immutable zotio plan after SHA-256 confirmation

papio zotio apply <plan-id> [flags]
Flag Type Default Description
--confirm-sha256 string Exact confirmation SHA-256 printed by papio zotio plan

papio zotio import-backfill

Backfill stranded ready papers into Zotero (dry-run by default)

Deliver validated ready jobs whose Zotero import never succeeded.

Dry-run is the default: the command reports what it would import, which papers are already owned (and would be marked duplicate), and which are expected to fail (for example bundle validation on an empty title). Pass --apply to write to your library.

Jobs submitted without policy.auto_import are excluded unless you pass --include-not-requested, because importing them was never requested.

papio zotio import-backfill [flags]
Flag Type Default Description
--apply bool false apply imports to the configured Zotero library (default is dry-run)
--cursor string resume after the cursor returned by a previous invocation
--include-not-requested bool false include ready jobs that did not request policy.auto_import
--limit int 50 maximum jobs per invocation (1-50)

papio zotio plan

Export ready jobs and preview exact zotio mutations

papio zotio plan <job-id> [job-id...]

papio zotio preflight

Verify the configured zotio version and capabilities

papio zotio preflight

papio zotio tags

Manage the exception-tag ledger on linked Zotero items

papio zotio tags

papio zotio tags reconcile

Converge papio:needs-action / papio:unavailable tags with current job states

Run now the papio-owned tag pass that the daemon runs automatically. It writes to Zotero immediately, with no preview.

papio zotio tags reconcile

papio zotio tags retractions

Preview or apply the papio:retracted tag on items with a verified retraction notice

Previews by default: lists the Zotero items whose DOI exactly matches a current verified retraction notice and the papio-owned tags no longer warranted. --apply writes the automatic papio:retracted tag and removes only papio-owned ones. Corrections and expressions of concern are never tagged, a manual tag is never changed, and acknowledging the inbox alert does not remove the tag. With zotio.retraction_tags off, --apply only removes papio-owned tags.

papio zotio tags retractions [flags]
Flag Type Default Description
--apply bool false Write the changes instead of only previewing them