Skip to content

Privacy policy

Last updated: 2026-09-20

papio runs on your computer. It has no hosted service, user account, telemetry, or analytics. This policy covers the papio application (daemon and CLI) and the papio browser extension.

Summary

papio does not collect your data or send it to OrgMentem.

The extension communicates with the local papio application through the browser's native-messaging interface. It does not contact OrgMentem or any other external service on its own, except when it asks a provider page to turn a link into a PDF URL.

The local application does contact third-party scholarly services to find papers. These requests include the identifier you ask papio to resolve, such as a DOI, PMID, arXiv ID, or title. Some services also receive your configured email address or API credentials. The table below lists every destination and the data it receives.

If you configure the optional agent acquisition backend, the daemon also sends a limited article observation to TypeSafe as described below.

Requests to third-party services

Every destination below is contacted directly by the daemon on your computer. Most requests carry the identifier being looked up; the retraction-check fetch downloads a shared dataset instead and carries no library identifiers. The “Data sent besides the lookup” column lists anything else sent.

Service Data sent besides the lookup Used for Default
api.typesafe.ai your TypeSafe key; article DOI, bounded article title, sanitized visible control labels/roles/disabled states, opaque IDs and observation revision Optional agent acquisition decisions Off — requires explicit papio config agent set enrollment or PAPIO_TYPESAFE_API_KEY in the daemon environment
api.unpaywall.org your email (required by their terms) Resolving a DOI On
api.crossref.org your email, if set Adding metadata to a title-only request; checking a DOI's registered version relations when other candidates are exhausted On
api.labs.crossref.org your email, if configured Daily retraction checks for papers papio acquired (and your wider library when retraction.scope = "library") On
www.ebi.ac.uk (Europe PMC) — Resolving a DOI, PMID, or title On
export.arxiv.org — Resolving an arXiv ID or DOI, and papio search when configured On
doi.org your email, in the User-Agent Confirming that a DOI exists before an institutional handoff On
Your institution's configured delivery API (document_delivery.base_url — ILLiad in v1) your api_key, patron_ref, and the request's bibliographic identifiers Submitting or polling one of your document-delivery requests Off — requires configuration
api.openalex.org your email, your API key papio search and watches (the default discovery backend) On
api.openalex.org your email, your API key Resolving On (disable with [sources.openalex] enabled = false)
api.core.ac.uk your API key Resolving Off
api.crossref.org (TDM) your subscriber token Resolving Off
api.semanticscholar.org your API key, if set Resolving a DOI, arXiv ID, or PMID, and papio search when configured On
api.openaire.eu your personal access token, or the access token exchanged from your client credentials, if set Resolving On
aai.openaire.eu your OpenAIRE client_id and client_secret (HTTP Basic), sent only to this token endpoint Exchanging them for a short-lived access token that api.openaire.eu then receives Off — active only when an openaire_client credential (papio config credentials set sources.openaire) is configured
iris.who.int, and any host you list in open_books.dspace_servers the ISBN; your email, in the User-Agent Resolving a request whose only identifier is an ISBN On (iris.who.int only)
library.oapen.org the ISBN; your email, in the User-Agent Resolving a request whose only identifier is an ISBN Off; open_books.oapen = true enables it
Publisher and repository hosts — Downloading the PDF On
api.github.com nothing Once a day, checking for a new papio or zotio release On if you ran papio init (it enables updates.check unless you decline or pass --check-updates=false); the config key itself defaults to false. updates.check = false disables it
raw.githubusercontent.com nothing Once a day, fetching the signed adapter control file that can suspend a broken browser adapter Follows updates.check, and only in a build that embeds the papio control key. updates.check = false disables it
Your webhook URL job event and message Job state changes Off

Important details

Email address. The email setting is sent to services that require or accept it. Unpaywall and OpenAlex require an email address. Crossref metadata, Retraction Watch, and DOI lookup use it when configured. The open_books repositories receive it in the User-Agent (IRIS on by default; OAPEN when open_books.oapen is on). Leaving it empty prevents Unpaywall and OpenAlex lookups.

Retraction checks. Retraction checks download the Retraction Watch dataset and match the DOIs of papers papio acquired (or, with retraction.scope = "library", your wider library) locally on your machine; the request carries no library DOIs, only your configured email as a mailto parameter when one is set. Disable them with [sources.retraction_watch] enabled = false. With zotio.retraction_tags = true, a verified retraction is also written into your own Zotero library as the papio:retracted tag; that step looks up each retracted DOI through your local zotio and sends nothing to a third party.

Update checks. The updates.check key defaults to false, but papio init enables it unless you decline the prompt or pass --check-updates=false. When enabled, update checks make an unauthenticated request to the public GitHub releases page. GitHub receives your IP address, as it would for any web request, but papio does not send your identifiers or usage information. Disable the check with updates.check = false.

Adapter control. With the update check on, the daemon also fetches one small signed file from raw.githubusercontent.com once a day (change the address with updates.control_url). The request is an anonymous GET, like the release check: the host receives your IP address and nothing else, and papio sends no identifier, count, or usage information. The file can only name packaged adapter revisions and safety domains to suspend; it carries no host, selector, path, or URL for the browser to act on. The daemon accepts it only when an Ed25519 signature verifies against the papio control key built into the binary, and it never accepts an older file than the one it holds. A suspended adapter stops downloading by itself and the paper waits for you in the inbox; papio doctor names the suspension. A missing file (HTTP 404) means nothing is published. The browser extension makes no request of its own and keeps only the last accepted sequence number and a digest in its local storage.

Document delivery. Document delivery is disabled unless you configure it. When enabled, papio contacts only the institution's configured delivery service and sends the credentials and bibliographic details required by that service. It never uses a shared or papio-operated delivery service. See the configuration reference for the full field list.

Browser extension

  • No OrgMentem data collection. The extension has no backend and does not send data to OrgMentem. It communicates with the local native-messaging host com.orgmentem.papio.
  • No browser credentials leave the page. You enter institutional credentials and complete MFA or CAPTCHA in your browser. The extension never reads a password field, a cookie, or your browsing history, and it never stores or transmits a username or a session token. To tell whether your library session is live, the check it runs inside the configured library page does read that page's own visible affordances and its localStorage and sessionStorage entries, including whether a session token found there has expired and whether it carries an identity claim. Every value is discarded in the page: only the resulting signed in / signed out / unknown classification comes back, and nothing else is stored or sent.
  • No background scraping, and scanning is explicit. Page scanning runs only when you click it, reads only the top frame of that one tab, and runs entirely inside the page: identifier detection is local JavaScript, not a network request. Your explicit click is the consent for that one scan; no separate site approval exists. Selection acts only on the papers you choose, with a maximum of 200 canonical keys per durable cohort, submitted in bounded chunks. It does not crawl, harvest, or auto-submit pages.
  • Institution-session checks follow your local keep-warm mode. The default While papio has work mode checks the configured library resolver only while institutional papers are active. Always for current library keeps that resolver warm even when no paper currently needs it. Off stops automatic resolver checks. When a paper is waiting for sign-in, a completed HTTPS navigation on that paper's declared publisher host can schedule a check of the configured library resolver. This publisher-triggered path reads no publisher page content. The publisher page cannot set the popup's signed-in or signed-out verdict; that comes only from the configured library page. If papio's own resolver tab is still paused on an identity-provider page, the trigger leaves that page open and creates a muted background resolver tab for the check. The replacement surfaces only when the resolver itself says that sign-in is still required. A tracked papio tab returning from authentication can still provide the existing, same-origin release evidence for queued work, subject to current resolver access. Other hosts, queued-only work, missing institution bindings, and ambiguous institutions do not authorize this trigger. No new landing URL, page-derived publisher data, title, path, query, fragment, cookie, credential, or session token enters extension storage or a native message.
  • What a scan sends to the local application. The scan itself sends nothing. When the selection workspace opens, the detected identifiers (each a doi, pmid, arxiv, or openalex kind and value) plus a structural count of visible records go to the local papio application so it can mark which papers you already own and which are eligible. When you submit, only the canonical keys of the rows you selected are acquired, along with the page's bare lowercase HTTPS origin and the detector name. The short citation label shown beside each row — up to 240 characters of the nearest citation-shaped container's visible text — is display-only and stays in the browser; it is never sent. No page text, path, query, fragment, page title, or credential leaves the browser for a scan.
  • The host-page action acknowledgement is ephemeral and local. When a popup action succeeds and transient acknowledgements are set to show for all requests, the extension briefly draws a small chip in the page you acted on. It carries one of four fixed short phrases and nothing else — no identifier, title, URL, provider name, or job id — is not interactive, sends nothing anywhere, stores nothing, and removes itself after three seconds. It reads no page content and installs no watcher or content script.
  • The loss toast prefers the page when all-sites access is active. When papio loses a tab it opened for a paper, it can offer to reopen that route. With all-sites access granted, "Show the lost-tab message in the page you are reading" is on by default and draws the message into the page in front of you. Turn it off to use the small papio window instead. Revoking all-sites access turns the in-page route off, and re-granting access does not restore an explicit opt-out. Both routes show the same fixed sentence, one button, and papio's own mark. They carry no identifier, title, URL, provider name, or job reference, disappear eight seconds after arriving, and commit nothing when they go. Neither appears while a papio surface holds focus.
  • The in-page loss message reads nothing. The all-sites grant lets papio reach the current HTTPS page. The loss-toast setting selects the integrated route or the separate window. When papio draws the message, it adds one element and reads nothing from the page. No selector runs, no page text is collected, and nothing about the page is stored or sent. The message renders inside a shadow root, so the page's scripts and styles do not reach it. It removes itself before reporting your choice. It is never drawn into a page papio is driving, a non-HTTPS page, or a PDF. A withdrawn grant, blocked injection, or unsafe page always falls back to papio's own window.
  • Focused-surface presence is minimal and local. The feature-gated surface_presence_v1 hint carries only an opaque per-instance id, the focused surface type (popup or inbox), a boolean focused value, and a timestamp. It goes to the local daemon only. It contains no URL, title, tab id, host, identifier, or page content.
  • Page-bulk recovery is origin-bounded. The browser-local restart-safe cohort record stores only a bare lowercase HTTPS origin, a bounded detector identifier, and canonical keys (plus the recovery bookkeeping needed to replay chunks). It stores no path, query, fragment, page title, or bearer value.
  • Ownership marks come from a local check, not the network. A page-bulk row's owned_with_pdf / owned_missing_pdf / ownership_unknown marks can come from your Zotero library through zotio, which the local application invokes as a local subprocess in local-only mode: the lookup answers from zotio's existing on-disk library mirror, and no network request is made for this check — in particular, papio never triggers a Zotero-account sync from a workspace scan. The mirror refreshes only through your own zotio activity (for example, when a paper is filed after acquisition), so a stale or failed check reports ownership_unknown honestly rather than a false "not owned."
  • Normal browser session. The extension uses browser extension APIs and native messaging. It does not use WebDriver, CDP, or other browser-automation frameworks.

Local storage

Browser storage. The extension stores its settings and temporary job and tab state in browser storage. This data stays in the browser so the extension can survive service-worker suspension and reconnect to the local application. For an active institutional job, browser storage can also retain the configured library resolver as one bare HTTPS origin. A pending session-recheck reason can survive service-worker suspension beside it. Neither value contains the publisher landing, an identity-provider address, a path, query, fragment, title, cookie, credential, or permission pattern.

The dedicated page_bulk_cohort_recovery_v1 browser-local record is limited to restart-safe replay data: a bare lowercase HTTPS origin, a detector identifier, and the ordered canonical keys, together with opaque cohort/chunk bookkeeping and timestamps. It never stores a path, query, fragment, page title, or bearer value.

Browser storage for page scanning. Page scanning requires an explicit click for each scan. The browser stores only the restart-safe page-bulk cohort record described above, with no path, query, fragment, page title, or bearer value.

Application storage. The local application stores papers, metadata, and job records in its data directory. Validated PDFs live in artifacts/. Downloaded candidates awaiting validation live in quarantine/. Papers go only to your own Zotero library if you enable that integration. Notification routing also keeps the notification_intents ledger in papio.db; its payloads are durable and may retain identifiers such as a retraction finding's DOI indefinitely. For a single-finding integrity notice, the DOI may also appear in the macOS Notification Center notification text, subject to your operating system's notification and lock-screen settings.

Diagnostic captures. Diagnostic captures are sanitized HTML from pages you choose to capture. They are stored in <data_dir>/captures/<host>/ and may still contain article text, account labels, or other page content. Sanitization removes scripts, query strings, form values, token-shaped values, email addresses, and IPv4 and IPv6 addresses; some provider error pages print your IP address. A capture whose sidecar records sanitizer_version 1 predates the address rule and may still contain your IP address. Captures are retained for 14 days and up to 10 per host by default; both limits are configurable in [captures]. Run papio adapter captures purge --all to remove every capture, or papio adapter captures purge --host <host> to remove captures for one host.

Bug reports. The data directory may also contain papio.db (request history, titles, identifiers, and notification-intent payloads), native-host.log (browser-session diagnostics, including URLs), a legacy adoptions/ directory on installs that predate the browser-download adoption root, and the update-cache*.json and retraction-cache.json files. Browser-downloaded files awaiting adoption now live in the adoption root itself (<your download folder>/papio by default). papio does not upload any of these. Review and minimize them before sharing a bug report; they describe what you have been reading.

Adapter evidence. Reaching a provider with no adapter can create a sanitized diagnostic capture, but papio never uploads it, opens a public issue, or sends telemetry. Review and minimize a capture before sharing it yourself. Sanitized HTML can still contain article text, account labels, or other page content.

Acquisition history and impact figures. The extension's figures — papers acquired, success rate, weekly acquisition trend, access-route breakdown, and human-handoff rate — are calculated locally from job records. They are displayed only to you and are never transmitted anywhere.

Agent acquisition

Saving a key with papio config agent set, or supplying PAPIO_TYPESAFE_API_KEY to the daemon, enables cloud decisions for eligible delegated acquisitions. The extension sends the local daemon a matching article DOI, a title of at most 400 characters, and at most 80 visible article controls with labels of at most 240 characters. TypeSafe receives that projection and your TypeSafe credential. The projection excludes page URLs, document bodies, form values, browser credentials, account areas and unrelated tabs. URL-like and credential-like strings in labels are redacted. Labels are page-derived text; this minimization is not a guarantee that all possible personal text is detected.

Saved integration credentials use macOS Keychain, Windows Credential Manager or Linux Secret Service. Config stores typed references; it does not receive resolved secrets. References survive config moves but do not sync secrets to another machine. Each profile explicitly chooses its records, and TypeSafe setup enrolls only that profile. Webhook records include the complete endpoint URL because its path or query can contain a token.

An explicit environment reference supports headless use. Selected variables are removed before child processes start. The older PAPIO_TYPESAFE_API_KEY override still works until the profile has an explicit agent reference; an empty legacy value disables the backend. papio config agent remove detaches enrollment; remove any legacy environment override and restart the daemon to disable it. Detaching does not delete a shared OS record. Deletion is a separate explicit credential command.

Legacy TOML secrets remain supported until you run papio config credentials migrate. Migration verifies new records before replacing config, refuses observed concurrent edits, leaves old TypeSafe records intact and saves the previous config to config.toml.bak (mode 0600). That file can still hold the literal secrets, so delete it after you check the result. Credential status reports local availability without printing values; it does not claim the provider has authenticated them. Browser passwords, cookies and SSO remain browser-owned; Zotero credentials remain zotio-owned.

The daemon retains request/permit IDs, observation revisions, outcomes and usage counts locally. It does not retain the model projection or raw response in those receipts. Existing diagnostic captures remain separate and local. No repair trace or analytics is sent to OrgMentem. The decision interface also accepts local backends without cloud credentials; a local model runtime is not yet bundled.

For Firefox agent downloads, the extension sends the local daemon the exact browser download path, size, start time and download ID. The path stays local and is not retained in the job's event receipts or sent to the model. The daemon copies only a new file from its configured download directory and keeps the browser's original file. A restart before publication can leave an incomplete attempt; Papio does not repeat the click to recover it.

Permissions

Each browser permission is used to perform a requested download, read a page needed for that job, run an explicit one-shot scan of the current tab, check a configured library session while a paper is waiting for sign-in, or report a result to the local application. For example, nativeMessaging reaches the local daemon, downloads saves the requested PDF, activeTab permits the top-frame scan only after you click it, and host permissions allow the extension to read the relevant library and publisher pages. On Firefox only, webRequest, webRequestBlocking and webRequestFilterResponse let the extension keep a copy of a publisher's one-time PDF response in a tab papio opened for a paper, and save it to your download folder; the bytes do not leave your computer. The extension store listing explains each permission in detail.

Third parties

papio does not sell your data or share it for advertising, credit decisions, or unrelated purposes.

The third-party scholarly services in the table receive the data listed there because they are needed to find or download the paper you requested. During browser handoff, your browser contacts your institution and the publisher directly. papio is not an intermediary for those requests.

Changes

If this policy changes, the “Last updated” date above will change. The current version will always be available at this URL.

Contact

Questions about privacy: open an issue at github.com/OrgMentem/papio.