Push a Markdown file from a terminal and get its link back. One file of JavaScript with no dependencies, talking to the same API and the same converters as the site.
Read the command-line reference
`cli/tp.mjs` in the public repository is a client for the same API. It is a single file with nothing to install beside it, because a tool that runs in CI should not drag a package tree behind it, and it needs Node 20 or later.
From a checkout it runs as `node cli/tp.mjs`; its package names the command `tp`, which is how the examples on this page are written. `tp --help` lists every command and flag.
It is also what the GitHub Action runs, so a command that works on your machine behaves the same way in a workflow.
`tp push README.md --share` converts the file, keeps it in your account and prints its link. A pushed `.html`, `.csv`, `.tsv`, `.json` or Evernote `.enex` is converted to Markdown by the server on the way in, rather than stored as if it already were Markdown.
Files the API takes as bytes rather than text — `.docx`, `.xlsx`, `.pptx`, `.epub`, `.odt`, `.rtf` and export zips — are refused, with the address of the page on the site that reads them in a browser.
`--merge` chains several Markdown files into one document, in the order given, with a rule between them, and `--name` names it: `tp push docs/*.md --merge --share --name handbook.md`.
`--share` makes a link anybody holding it can open, and `--share people` keeps the document to named readers, whose addresses you add on the site. `--expires 7d`, `12h` or `2026-12-31` ends the link — a bare date at the end of that day where you are — and `--password` protects it with a password read from `TP_SHARE_PASSWORD`, never from an argument, where it would stay in your shell history.
`tp push notes.md --update <id>` sends new text to a document that already exists. Its id, its link, its password and its end date stay as they were, and the text it replaced is kept on the server as a revision, the newest ten of them. Pushing the same text again changes nothing.
`--replaces <id>` does the opposite on purpose: it makes a new document, with an id of its own and a link of its own when it is shared, and records it as the next version of an earlier one, which `tp versions <id>` lists as a chain. A link already sent keeps showing what it showed.
`tp list` shows what is in the account, and `--q` searches the documents’ text. `tp rm <id>` moves a document to the Trash, where it waits 14 days; `tp usage` prints how much of the 250 MB and the 5,000 documents is used; `tp summary <id>` asks for a short summary, made once and cached.
`--folder "Team/Notes"` on a push files the document by its path and makes any part of the path that is not there yet. `tp folders` prints the tree with ids, `tp mkdir` and `tp mv` make and move, `tp rmdir` removes a folder and moves what it held up a level, and `tp share-folder` shares a whole folder with `--link`, `--people` or `--private`, taking the same `--expires` and `--password`.
`tp login tp_live_…` saves a key to `~/.config/tp/config.json`, readable only by you. A key can also come from `--key` or from `TP_API_KEY`, which are read first; the environment variable is the one for CI, since `tp login` leaves the key in your shell history.
`--json` prints the API’s own answer instead of the summary lines, which is what the Action reads, and `TP_HOST` points the tool at another deployment. A failure prints the API’s message with its status and exits non-zero, so a script or a pipeline stops where it should.