Example C · Send a File¶
Send an encrypted file from the gateway — small files via relay, large files via QUIC when both peers support it.
Prerequisites¶
- Gateway running with an active peer chat (Example B)
- Active license
- File available inside the container at the path you pass to
send-fileorprivitty_send_file
Paths are inside the container
/Users/.../Desktop/file.pdf on your Mac is not visible to the daemon. Use a container path such as /data/file.pdf.
Step 1 — Make the file available inside the container¶
Choose one of the three options below.
Option A — Bind mount (best for production)¶
Add a host folder when you start the container. Files dropped on the host appear inside the container automatically — no docker cp needed.
mkdir -p ~/privitty-outbox
docker run -d \
--name privitty-edged \
--restart unless-stopped \
-e PRIVITTY_PROFILE=factory-gw-01 \
-e PRIVITTY_LICENSE_URL="https://plm.privittytech.com/v1/license/YOUR_TOKEN" \
-p 127.0.0.1:7200:7200 \
-v privitty-data:/var/lib/privitty \
-v ~/privitty-outbox:/data \
privitty/edge:latest
Copy a file to the host folder — it is immediately at /data/ inside the container:
cp ~/Desktop/env/environmental_monitoring.pdf ~/privitty-outbox/
# Inside container: /data/environmental_monitoring.pdf
Bind mount must be set at container start
You cannot add -v ~/privitty-outbox:/data to a container that is already running. If you started without this mount, use Option B below or recreate the container (your privitty-data volume is preserved).
Mount must be writable
Do not use :ro on /data — encryption writes filename.pdf.prv alongside the original.
Option B — docker cp (quick test, container already running)¶
Copy a file from your Mac into the running container:
Use the container path in the next step: /data/environmental_monitoring.pdf.
If /data does not exist yet, copy to the accounts volume instead:
docker run --rm -v privitty-data:/var/lib/privitty alpine:3.19 mkdir -p /var/lib/privitty/staging
docker cp ~/Desktop/env/environmental_monitoring.pdf \
privitty-edged:/var/lib/privitty/staging/
# Container path: /var/lib/privitty/staging/environmental_monitoring.pdf
Option C — Stage via the named volume (no container recreate)¶
Copy from your Mac into privitty-data using a temporary Alpine container:
docker run --rm \
-v privitty-data:/var/lib/privitty \
-v "$(pwd)":/incoming:ro \
alpine:3.19 \
sh -c "mkdir -p /var/lib/privitty/staging && cp /incoming/environmental_monitoring.pdf /var/lib/privitty/staging/"
Container path: /var/lib/privitty/staging/environmental_monitoring.pdf
Step 2 — Send with the CLI (recommended — encrypt + deliver in one command)¶
The privitty-edge send-file command inside the container performs encryption and delivery — the same as running ./privitty-edge send-file on bare metal.
docker exec privitty-edged \
privitty-edge --accounts /var/lib/privitty send-file \
--chat 12 \
--file /data/environmental_monitoring.pdf \
--message "Sending a CDR file" \
--allow-forward \
--duration 40
Expected output:
Sending 'environmental_monitoring.pdf' (0.0 MB) via Privitty …
allow_download=false allow_forward=true duration=40 min
Encrypted → /data/environmental_monitoring.pdf.prv
File ID : 1
✓ File sent via SMTP (msg_id=22)
| Flag | Meaning |
|---|---|
--chat |
Chat ID from privitty-edge chats |
--file |
Path inside the container |
--message |
Caption sent with the attachment |
--allow-forward |
Recipient may forward the file |
--allow-download |
Recipient may save the decrypted file (off by default) |
--duration |
Access window in minutes (0 = unlimited) |
List chats to find the chat ID:
Step 3 — Send with curl (two RPC calls)¶
There is no single JSON-RPC method that encrypts and sends together. Use two calls, or the CLI above.
3a — Resolve peer contact ID (chat 12, 1:1):
curl -s -X POST http://127.0.0.1:7200/rpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"get_chat_contacts","params":[1,12],"id":1}' | jq .
Contact 1 is self; the other ID is the peer.
3b — Encrypt:
curl -s -X POST http://127.0.0.1:7200/rpc \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"privitty_send_file",
"params":[1,12,12,"/data/environmental_monitoring.pdf",false,true,40],
"id":2
}' | jq .
Params: [account_id, chat_id, peer_contact_id, path, allow_download, allow_forward, duration_minutes]
3c — Deliver (use encrypted_path from step 3b):
curl -s -X POST http://127.0.0.1:7200/rpc \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"send_msg",
"params":[1,12,{
"text":"Sending a CDR file",
"file":"/data/environmental_monitoring.pdf.prv",
"viewtype":"File"
}],
"id":3
}' | jq .
See Curl Cookbook · Send an encrypted file for a one-liner shell script that chains both RPC calls.
Transfer paths¶
| File size | Path | Notes |
|---|---|---|
| Small (< ~20 MiB) | Relay (IMAP/SMTP) | Encrypted .prv travels as a standard attachment |
| Large (≥ ~20 MiB) | QUIC (iroh P2P) | Peer receives a QUIC offer; no send_msg attachment needed |
The CLI and daemon handle path selection automatically.
Monitor progress via SSE:
Look for PrivittyFileEncrypted and MsgDelivered.
Step 4 — Revoke access (optional)¶
Or via curl — see Curl Cookbook · Revoke.
Next¶
- Example D · SSE Streaming — automate event handling
- Curl Cookbook — all API commands