Usage guide

← Home

Quick start

# send a file — password auto-generated, prints link + password
$ ttl send secret.pdf
No password provided. Generate one? [Y/n]:
Generated password: aB3kL9mX
·✧★◉ Thank goodness, secret.pdf is in orbit (1.2 MB)
IMPORTANT! Save your password — required to download and decrypt the file.
Password: aB3kL9mX
https://ttl.space/aBcDeFgHiJ

# download — prompts for password interactively
$ ttl get https://ttl.space/aBcDeFgHiJ
Enter password: ********
Password verified
◉★✧· Phew, secret.pdf landed safe and sound (1.2 MB)

The CLI handles encryption, upload, download, and decryption. The server never sees your password or plaintext data.

Install

Homebrew (macOS)

$ brew install tweenietomatoes/ttl/ttl

Scoop (Windows)

$ scoop bucket add ttl https://github.com/tweenietomatoes/scoop-ttl
$ scoop install ttl

Pre-built binary

# download for your platform from releases
$ curl -Lo ttl.tar.gz \
  https://github.com/tweenietomatoes/ttl/releases/latest/download/ttl_linux_amd64.tar.gz
$ tar xzf ttl.tar.gz && sudo mv ttl /usr/local/bin/

Go install

$ go install github.com/tweenietomatoes/ttl/cmd/ttl@latest

From source

$ git clone https://github.com/tweenietomatoes/ttl
$ cd ttl && go build -o ttl ./cmd/ttl/
$ sudo mv ttl /usr/local/bin/

Verify

$ ttl version
ttl v1.3.0

Sending files

Basic send

# auto-generate password, default 7d TTL
$ ttl send report.xlsx

When no password is provided in a terminal, the CLI asks:

No password provided. Generate one? [Y/n]:

Press Enter or type y to auto-generate.

Custom password

$ ttl send -p mySecretPass -t 1h document.pdf

Burn after reading

# file is permanently deleted after the first download
$ ttl send -b photo.jpg

Custom TTL

$ ttl send -t 5m temp-credentials.txt   # expires in 5 minutes
$ ttl send -t 30m meeting-link.txt      # expires in 30 minutes
$ ttl send -t 6h backup.tar.gz          # expires in 6 hours
$ ttl send -t 1d daily-report.pdf       # expires in 1 day
$ ttl send -t 3d project-archive.zip    # expires in 3 days
$ ttl send -t 5d design-assets.zip      # expires in 5 days
$ ttl send report.xlsx                  # expires in 7 days (default)

Downloading files

Interactive (terminal)

$ ttl get https://ttl.space/aBcDeFgHiJ
Enter password: ********
Password verified
◉★✧· Phew, document.pdf landed safe and sound (4.2 MB)

The password is not echoed to the terminal. The original filename is preserved.

With token only

# you can use just the 10-character token instead of the full URL
$ ttl get aBcDeFgHiJ
Enter password: ********
Password verified
◉★✧· Phew, document.pdf landed safe and sound (4.2 MB)

Output directory

$ ttl get -o ~/Downloads aBcDeFgHiJ

By default, files are saved to the current directory. Use -o / --output to specify a different directory.

With password flag

$ ttl get -p mySecretPass https://ttl.space/aBcDeFgHiJ

Browser

You can also download and decrypt files in your browser by visiting the link directly. The web interface uses the same encryption library and prompts for your password. No software installation needed.

Password handling

The password is the encryption key seed. It never leaves your device and is never sent to the server. There are five ways to provide it:

1. Auto-generate (send only)

$ ttl send notes.txt
No password provided. Generate one? [Y/n]: y
Generated password: aB3kL9mX

Generates a cryptographically random 8-character password from [0-9A-Za-z]. Only available during send in a terminal.

2. Interactive prompt

$ ttl send notes.txt
No password provided. Generate one? [Y/n]: n
Enter password: ********
Confirm password: ********

$ ttl get https://ttl.space/aBcDeFgHiJ
Enter password: ********

Password is not echoed. During send, you choose whether to auto-generate; if you type your own, you confirm it. During get, you are prompted directly.

3. Flag: -p / --password

$ ttl send -p mySecretPass file.zip
$ ttl get --password mySecretPass https://ttl.space/aBcDeFgHiJ
-p / --password is visible in ps aux output and may be saved in shell history (~/.bash_history). Avoid in shared environments and scripts. Use --password-stdin or --password-file instead.

4. Stdin: --password-stdin

# pipe from echo
$ echo "mySecretPass" | ttl send --password-stdin backup.tar.gz

# pipe from password manager
$ pass show ttl/key | ttl send --password-stdin data.zip

# pipe from environment variable
$ printenv MY_SECRET | ttl get --password-stdin https://ttl.space/aBcDeFgHiJ

# heredoc
$ ttl send --password-stdin report.pdf <<<"mySecretPass"

Reads the first line from stdin. Useful in scripts, CI/CD pipelines, and automation. When stdin is not a terminal and no password source is provided, the CLI exits with an error (unless --json is used, which auto-generates a password).

5. File: --password-file

$ ttl send --password-file /run/secrets/key report.xlsx
$ ttl get --password-file ~/.ttl-key https://ttl.space/aBcDeFgHiJ

Reads the first line of the file (trailing newline stripped). Compatible with Docker secrets (/run/secrets/), Vault agent files, and similar patterns.

6. Auto-detected file: ttl.password

If no explicit password is given, the CLI looks for a ttl.password file next to the binary, then ~/.ttl/password. The first line is used as the password. This is useful for shared machines or kiosks where the same password is reused across transfers.

Only one explicit password source can be used at a time. Combining -p / --password, --password-stdin, and --password-file is an error. The auto-detected ttl.password file is only checked when none of these are given. Minimum password length is 8 characters.

Options reference

Send flags

FlagDescriptionDefault
-p, --password PEncryption passwordinteractive
--password-stdinRead password from stdin
--password-file FRead password from file
-t, --ttl DURTime to live7d
-b, --burnBurn after reading (single download)off
--timeout DURTransfer timeoutauto
--server URLServer URLhttps://ttl.space
-h3, --http3Try HTTP/3 (QUIC), fall back to TCPoff
--jsonOutput JSON to stdout (for scripts and AI agents)off

Get flags

FlagDescriptionDefault
-p, --password PDecryption passwordinteractive
--password-stdinRead password from stdin
--password-file FRead password from file
-o, --output DIROutput directorycurrent directory
--timeout DURTransfer timeoutauto
-h3, --http3Try HTTP/3 (QUIC), fall back to TCPoff
--jsonOutput JSON to stdout (for scripts and AI agents)off

TTL values

Free: 5m 10m 15m 30m 1h 2h 3h 6h 12h 24h 1d 2d 3d 4d 5d 6d 7d

Orbit adds: 14d 15d 28d 30d

Timeout

Default: auto — estimated from file size at 1 Mbps + 2 minute margin (minimum 5 minutes). Override with --timeout 10m or --timeout 1h.

Examples

Script: backup and upload

#!/bin/bash
tar czf /tmp/backup.tar.gz /data
echo "$BACKUP_KEY" | ttl send --password-stdin -t 6h /tmp/backup.tar.gz
rm /tmp/backup.tar.gz

Pipe link to clipboard (macOS)

$ ttl send -p mypass123 file.pdf | pbcopy

Pipe link to clipboard (Linux)

$ ttl send -p mypass123 file.pdf | xclip -sel clip

Burn: one-time secret

$ echo "$DB_PASSWORD" | ttl send --password-stdin -b -t 5m credentials.env
# link works exactly once, expires in 5 minutes

JSON mode (scripts & AI agents)

# send — password auto-generated in JSON mode
$ ttl --json send report.pdf
{"ok":true,"link":"https://ttl.space/xK9mQ2vLpA","filename":"report.pdf","size":2097152,"ttl":"7d","burn":false,"password":"aB3kL9mX"}

# get
$ ttl --json get -p aB3kL9mX xK9mQ2vLpA
{"ok":true,"filename":"report.pdf","size":2097152,"saved_to":"/home/user/report.pdf"}

# errors return ok:false
{"ok":false,"error":"Link not found"}

In --json mode, all output is structured JSON on stdout. If no password is provided during send, one is auto-generated and included in the response. Exit code is 0 on success, 1 on error.

Orbit plan

Orbit unlocks larger files (10 GB), longer retention (30 days), and file management (list & delete).

The API key is auto-detected from TTL_API_KEY env, ttl.key next to the binary, or ~/.ttl/key. Use ttl activate to save the key, or write it to any of these locations manually.

# activate your key
$ ttl activate ttl_orbit_aBcDeFgHiJ...
Orbit plan activated. Key saved to /usr/local/bin/ttl.key

# check plan and usage
$ ttl plan
Plan: orbit
Max file size: 10.0 GB
Max TTL: 30 days
Uploads per day: Unlimited

Usage:
  Uploads today: 3
  Active storage: 1.2 GB / 250.0 GB

# send with extended TTL
$ ttl send -t 30d large-backup.tar.gz

# list recent uploads
$ ttl list
  xK9mQ2vLpA    4.2 MB  2026-03-16 10:30 → 2026-04-15 10:30  [active]
  https://ttl.space/xK9mQ2vLpA
  rT7bNw3KpF  912.0 KB  2026-03-15 14:20 → 2026-03-17 14:20  [active (burn)]
  https://ttl.space/rT7bNw3KpF

# delete a file early
$ ttl delete xK9mQ2vLpA
Deleted: xK9mQ2vLpA

# remove stored key
$ ttl deactivate
Key file removed: /usr/local/bin/ttl.key

HTTP API

Upload and download require the CLI's encryption pipeline (Argon2id + XChaCha20-Poly1305 + chunked AEAD). Use ttl send / ttl get or --json mode for scripting. The endpoints below are for Orbit file management.

List files (Orbit)

$ curl https://ttl.space/v1/files -H "X-API-Key: ttl_orbit_..."
{"files":[{"token":"xK9mQ2vLpA","link":"https://ttl.space/xK9mQ2vLpA","size_bytes":1048576,"created_at":1711800600,"expires_at":1714392600,"burn":false,"expired":false}]}

Returns all files uploaded with this key. Requires Orbit plan.

Delete file (Orbit)

$ curl -X DELETE https://ttl.space/v1/files/xK9mQ2vLpA -H "X-API-Key: ttl_orbit_..."

Returns 204 No Content on success. Requires Orbit plan. The file must be owned by the given key.

Error responses

StatusMeaning
401Invalid or expired API key
403Feature requires Orbit plan
404File not found or not owned by this key
429Rate limit exceeded

Limits

ConstraintFreeOrbit
Max file size2 GB10 GB
Max TTL7 days30 days
Uploads per day10Unlimited
Storage quota250 GB
List & delete
Min password length8 characters
Requests per IP30 per 10 seconds
Connections per IP10 concurrent

Encryption

Files are encrypted on your device before upload. The server stores only ciphertext and cannot decrypt your files.

ComponentAlgorithm / Value
Key derivationArgon2id (time=3, memory=64 MB, parallelism=1)
CipherXChaCha20-Poly1305 AEAD

Any modification to the ciphertext causes decryption to fail. The server verifies that the downloader knows the correct password before releasing the ciphertext, using a one-way token derived from the encryption key.