--- name: shz-al description: Upload, fetch, update, or delete text/binary content via https://txtbin.pages.dev, a pastebin with a command-line client. Use when you need a quick URL for sharing long output, hosting a small file, shortening a URL, or rendering markdown as HTML. --- # shz.al A pastebin hosted on Cloudflare Workers at `https://txtbin.pages.dev`. Use the `pb` command-line client: it encrypts pastes on the client by default, remembers the passwords and keys of your uploads, and splits large files automatically. If `pb` is not available or you need plain HTTP, use `curl` as described in `https://txtbin.pages.dev/doc/curl.md`. ## Install `pb` `pb` needs `python3` with the `requests` and `cryptography` packages (`cryptography` is only needed for encryption, so `pb post -u` works without it). ```shell curl -fsSL https://raw.githubusercontent.com/SharzyL/pastebin-worker/goshujin/scripts/pb -o ~/.local/bin/pb chmod +x ~/.local/bin/pb pip install requests cryptography # or the python3-requests / python3-cryptography system packages export PB_DOMAIN=https://txtbin.pages.dev # not needed for https://shz.al, the default; or pass --base-url to every command ``` With Nix, skip `pip` and replace the first line of `pb` with the following, so that it runs in a Python environment with both packages (requires the `nix-command` and `flakes` experimental features): ```shell #!/usr/bin/env -S nix run --impure --expr '(import (builtins.getFlake "nixpkgs") {}).python3.withPackages (ps: [ ps.requests ps.cryptography ])' '' -- ``` ## Upload ```shell pb post -c 'hello, world' # text pb post file.png # file, stored with its filename | pb post # stdin pb post -u -c 'hello, world' # without encryption ``` The response is JSON: ```json { "lastModifiedAt": "2026-11-10T03:08:51.000Z", "createdAt": "2026-11-10T03:08:51.000Z", "expireAt": "2026-11-17T03:08:51.000Z", "sizeBytes": 40, "location": "KV", "encryptionScheme": "AES-GCM", "url": "https://txtbin.pages.dev/tkGQ", "manageUrl": "https://txtbin.pages.dev/tkGQ:XGxdkyeeMMF8fncbKJCpxbKc", "expirationSeconds": 604800, "decryptionUrl": "https://txtbin.pages.dev/d/tkGQ#EfPaKj_OyuPHZhoexwkrUK_iGEL8Ui6tiDUsZxmn2Uk" } ``` `decryptionUrl` is added by `pb` for an encrypted paste; everything else is the server's answer, where `sizeBytes` is the size of what was stored (the ciphertext here) and a `filename` field appears when a file was uploaded. Pastes are encrypted by default, so: - **Share `decryptionUrl`.** It opens the paste in a browser, which decrypts it with the key after `#`; the key never reaches the server. - `url` returns the ciphertext only. Upload with `-u/--unencrypted` when the paste must be readable by plain HTTP clients such as `curl`, or when it is used as a URL shortener. `pb` records the manage URL and the key in its history file (`~/.local/state/pb/history.jsonl`), so later `update`, `get` and `delete` calls on the same machine only need the paste name, and `pb list` shows the pastes uploaded from there. Keep `manageUrl` yourself if the paste may be managed from elsewhere — it is the only way to authenticate as the owner. ## Upload options - `-n ` — custom name (≥3 chars from letters, digits and `+_-[]*$@,;`, returned prefixed with `~`). - `-e ` — expiration: integer/float with unit `s`/`m`/`h`/`d` (default seconds). E.g. `-e 30m`, `-e 14d`; use `-e never` for permanent storage. - `-s ` — set a specific management password. - `-p` — private mode: 24-char unguessable random name. - `-F ` — filename stored with the paste. ## Fetch ```shell pb get # content, decrypted with the key from history pb get -K # decrypt with an explicit key pb get # any paste URL works; the endpoint and key come from it pb get --save [DIR] # save with the server-provided filename pb get --meta # JSON metadata (size, dates, …) ``` ## Update / delete ```shell pb update -c 'new content' # password looked up from history pb update -f file # endpoint and password come from the URL pb delete # prints nothing on success pb list # pastes uploaded from here, with their URLs ``` `pb list` prints a table: ``` NAME UPLOADED EXPIRES SIZE ENC FILENAME URL tkGQ 2026-11-10 11:08 6d 40 B yes https://txtbin.pages.dev/d/tkGQ#EfPaKj_OyuPHZhoexwkrUK_iGEL8Ui6tiDUsZxmn2Uk bPfn 2026-11-10 11:08 6d 9 B panty.jpg https://txtbin.pages.dev/bPfn ``` `update` accepts `-e`, `-s`, `-F` and `-u` like `post`; `-e` recalculates the expiration from now. An encrypted update uses a fresh key, so it prints a new `decryptionUrl` and the old one stops working. ## Other URL forms - `/d/` — display code with syntax highlighting. Append `?lang=` to override the highlighting language. - `/a/` — render a markdown paste as HTML (GitHub-flavored Markdown + MathJax). For an encrypted paste, append `#` like the decryption URL. - `/h/` — render a paste as a document (HTML unless the extension, `?mime=` or the uploaded filename says SVG or XML) in a sandboxed frame below a site header, after the viewer confirms a warning. This is the only URL that renders HTML: the raw URL serves HTML as `text/plain`. For an encrypted paste, append `#` like the decryption URL. - `/u/` — redirect to the URL stored in an unencrypted paste (URL shortener). - `/m/` — JSON metadata. ## Limitations - Default expiration is `never`, max finite expiration `90d`. Use `e=never` for a permanent paste that is not automatically expired; it remains until manually deleted. Finite durations are still capped by `MAX_EXPIRATION`. The server returns `permanent: true`, empty `expireAt`, and `expirationSeconds: null` for permanent pastes. - Max upload size is `256M`. - Only the content is encrypted; the name, filename, size and timestamps are visible to the server. - `never` disables application-level expiration, but it is not a backup or archival guarantee. Keep independent copies of important data; Cloudflare account/resource deletion or manual deletion can still remove a paste. ## Full docs - `https://txtbin.pages.dev/doc/curl.md` — comprehensive curl guide. - `https://txtbin.pages.dev/doc/api.md` — HTTP API reference. - `https://txtbin.pages.dev/doc/paste-crypto.md` — how paste encryption works.