CLI Usage with curl
A comprehensive guide to using this pastebin from the command line. For the full HTTP API reference, see api.md.
Conventions
<name>— the random name (e.g.abcd) or custom name (prefixed with~, e.g.~hitagi) of a paste.<passwd>— the password returned at upload time, used to update or delete the paste.<expire>— an expiration period: an integer or float, optionally suffixed withs(seconds, default),m(minutes),h(hours), ord(days). For example,300,30m,25d.
Uploading
Upload text content
$ curl -Fc='hello, world' https://shz.al
{
"url": "https://shz.al/abcd",
"manageUrl": "https://shz.al/abcd:w2eHqyZGc@CQzWLN=BiJiQxZ",
"expirationSeconds": 1209600,
"expireAt": "2026-05-21T10:33:06.114Z"
}
Save url for sharing and manageUrl for later updates or deletion.
Upload a file
$ curl -Fc=@panty.jpg https://shz.al
The original filename will be sent back as the Content-Disposition header
when the paste is fetched.
Upload from stdin
$ echo 'hello' | curl -Fc=@- https://shz.al
$ cat panty.jpg | curl -Fc=@- https://shz.al
Set an expiration
$ curl -Fc='kawaii' -Fe=300 https://shz.al # 300 seconds
$ curl -Fc='kawaii' -Fe=2h https://shz.al # 2 hours
$ curl -Fc=@big.bin -Fe=30d https://shz.al # 30 days
If e is not specified, the default expiration of the deployment is used. The
maximum expiration is also enforced by the deployment.
Use a custom name
$ curl -Fc='kawaii' -Fn=hitagi https://shz.al
{
"url": "https://shz.al/~hitagi",
...
}
The custom name is at least 3 characters long and may consist of letters,
digits, and +_-[]*$=@,;/. Note the leading ~ in the returned URL.
Because curl uses ; and , as field separators, names containing those
characters need to be wrapped in extra quotes:
$ curl -Fc=@panty.jpg -Fn='"hi/hello;g,ood"' https://shz.al
Set a custom password
$ curl -Fc='kawaii' -Fs=12345678 https://shz.al
If s is omitted, a random password is generated and returned in manageUrl.
Private mode (longer random name)
$ curl -Fc='secret' -Fp=1 https://shz.al
Without a custom name (n), p produces a 24-character random name, making
the paste effectively unguessable.
Mark a paste as syntax-highlighted
$ curl -Fc=@main.rs -Flang=rust https://shz.al
The lang field is sent back as the X-PB-Highlight-Language header on
fetching the paste, and is used by the display page (/d/<name>).
Fetching
Fetch raw content
$ curl https://shz.al/abcd
hello, world
Save the response to a file
$ curl https://shz.al/~panty.jpg -o panty.jpg
$ curl -OJ https://shz.al/~panty # use server-supplied filename
-J honors the Content-Disposition header set from the original filename.
Force download (attachment)
$ curl 'https://shz.al/abcd?a' -OJ
The ?a query string sets Content-Disposition: attachment.
Override mime type
$ curl 'https://shz.al/~panty.jpg?mime=image/png' \
-w '%{content_type}\n' -o /dev/null -sS
image/png
Or via path extension:
$ curl 'https://shz.al/abcd.json' -i
Pipe to another tool
$ curl https://shz.al/~panty.jpg | feh -
$ curl https://shz.al/~config | jq .
Conditional fetch with If-Modified-Since
$ curl -i -H 'If-Modified-Since: Wed, 01 May 2026 00:00:00 GMT' \
https://shz.al/~hitagi
HTTP/2 304
Inspecting metadata
$ curl https://shz.al/m/abcd
{
"lastModifiedAt": "2026-05-05T10:33:06.114Z",
"createdAt": "2026-05-01T10:33:06.114Z",
"expireAt": "2026-05-08T10:33:06.114Z",
"sizeBytes": 4096,
"location": "KV",
"filename": "a.jpg"
}
A HEAD request returns the same headers as GET without the body, useful
for quickly checking size and Content-Type:
$ curl -I https://shz.al/abcd
URL shortener
Upload a short URL, then redirect through /u/<name>:
$ curl -Fc='https://example.com/very/long/path' -Fn=ex https://shz.al
$ curl -L https://shz.al/u/~ex
Markdown rendering
Upload a markdown file and render it as HTML via /a/<name>:
$ curl -Fc=@README.md -Fn=readme https://shz.al
$ firefox https://shz.al/a/~readme
GitHub-flavored Markdown is supported, along with syntax highlighting and LaTeX math via MathJax.
Updating an existing paste
Use the manageUrl returned at upload time:
$ curl -X PUT -Fc='kawaii~' \
https://shz.al/~hitagi:22@-OJWcTOH2jprTJWYadmDv
PUT accepts the same fields as POST (c, e, s). Note that e
recalculates the expiration starting from the update time.
Deleting a paste
$ curl -X DELETE https://shz.al/~hitagi:22@-OJWcTOH2jprTJWYadmDv
the paste will be deleted in seconds
Deletion may take a few seconds to propagate globally.
Tips
-
Pipe long output through
jqto inspect upload responses:$ curl -sFc='hi' https://shz.al | jq -r .url -
Save the management URL into a variable to chain commands:
$ resp=$(curl -sFc=@notes.md https://shz.al) $ url=$(jq -r .url <<<"$resp") $ mgmt=$(jq -r .manageUrl <<<"$resp") -
For files larger than the
R2_THRESHOLDof the deployment, content is stored in R2 instead of KV transparently — no client change is needed. -
The maximum allowed upload size is set per deployment via
R2_MAX_ALLOWED. Exceeding it returns HTTP413.
Common errors
| Status | Meaning |
|---|---|
400 |
Malformed request (bad field, illegal name, bad expire). |
403 |
Wrong password when updating or deleting. |
404 |
Paste not found, or already expired. |
409 |
Custom name is already in use. |
413 |
Content exceeds the configured max size. |
500 |
Unexpected server error — please report it. |
For the full HTTP API including HEAD, OPTIONS, response headers, and edge
cases, see api.md.