Developers
Piggy Send API
Five endpoints cover upload, create, lookup, download and delete. All endpoints are POST with JSON bodies (except upload). Without a token, guest quota applies (1 GB, 7 days); send an API Token to use your account quota.
Download links are issued by the server after checking expiry and download count. All inputs are validated server-side, and quotas are enforced only on the server.
API Token
Add the X-Api-Key header to call the API with your account quota. Keep it secret — never commit it to a public repo.
/api/apps/6a9a6a33f8552c104c920ebc/integration-endpoints/Core/UploadFileStep 1: upload the file directly
Upload large files straight to the storage endpoint instead of proxying them through /functions (a proxied body hits the request-size limit and the function memory/timeout, showing up as 413 or 502). POST multipart/form-data with a file field, no auth required, and you get a file_url — pass it as file_uri to createTransfer in step 2. Files can be uploaded in parallel and there is no total cap.
curl -X POST https://piggysend.com/api/apps/6a9a6a33f8552c104c920ebc/integration-endpoints/Core/UploadFile \
-F "file=@./movie.mp4"{
"file_url": "https://…/movie.mp4"
}/functions/createTransferStep 2: create the transfer
Bundle the file_url values from step 1 (as file_uri) into one transfer with an expiry and download limit. The server validates each file size, the expiry and your transfer quota (guest 1 GB / signed-in 10 GB / Pro 1 TB, no total cap), then returns an unguessable short link.
curl -X POST https://piggysend.com/functions/createTransfer \
-H "Content-Type: application/json" \
-H "X-Api-Key: ps_xxx" \
-d '{
"title": "Weekend photos",
"message": "Check the last one!",
"files": [{ "name": "movie.mp4", "size": 734003200, "type": "video/mp4", "file_uri": "https://…" }],
"expires_in_days": 7,
"max_downloads": 10
}'{
"slug": "k3Jd9sLq2mXa7B",
"url": "https://piggysend.com/t/k3Jd9sLq2mXa7B",
"expires_at": "2026-09-11T06:50:00.000Z"
}/functions/getTransferGet transfer info
Fetch the public info of a transfer by slug: file names, sizes, downloads left, expiry and state.
curl -X POST https://piggysend.com/functions/getTransfer \
-H "Content-Type: application/json" \
-d '{ "slug": "k3Jd9sLq2mXa7B" }'{
"slug": "k3Jd9sLq2mXa7B",
"title": "Weekend photos",
"files": [{ "name": "movie.mp4", "size": 734003200, "type": "video/mp4" }],
"total_size": 734003200,
"max_downloads": 10,
"download_count": 2,
"expires_at": "2026-09-11T06:50:00.000Z",
"state": "active"
}/functions/downloadTransferGet download links
Returns download links after checking expiry and download count, and counts one download. Pass file_index for a single file, omit it for all files.
curl -X POST https://piggysend.com/functions/downloadTransfer \
-H "Content-Type: application/json" \
-d '{ "slug": "k3Jd9sLq2mXa7B", "file_index": 0 }'{
"files": [{ "name": "movie.mp4", "size": 734003200, "url": "https://…" }],
"expires_in": 300,
"download_count": 3
}/functions/chunked uploadLarge files: chunked upload
Split files over 10 MiB into 10 MiB (10485760-byte) parts and upload each part with step 1 (in parallel, retrying single parts on failure). Then upload a manifest JSON the same way, pass its URL as file_uri, and add chunked, chunk_size and chunk_count to the file entry in createTransfer.
# manifest.json
{
"version": 1, "name": "movie.mp4", "size": 734003200, "type": "video/mp4",
"chunk_size": 10485760,
"chunks": [{ "i": 0, "size": 10485760, "url": "https://…part0" }, …]
}
# createTransfer 中的文件项 / file entry
{ "name": "movie.mp4", "size": 734003200, "type": "video/mp4",
"file_uri": "https://…manifest.json",
"chunked": true, "chunk_size": 10485760, "chunk_count": 70 }{ "slug": "k3Jd9sLq2mXa7B", … }/functions/mergeDownloadMerged download (streaming, resumable)
Streams the original file while pulling its parts in order on the server; works for plain files too. Supports Range requests for resuming; only a request starting at byte 0 counts as a download. A single request lasts about 5 minutes at most, so resume very large files with Range, or fetch the parts yourself via the manifest_url from downloadTransfer.
curl -X POST https://piggysend.com/functions/mergeDownload \
-H "Content-Type: application/json" \
-d '{ "slug": "k3Jd9sLq2mXa7B", "file_index": 0 }' \
-o movie.mp4
# 续传 / resume
curl -X POST https://piggysend.com/functions/mergeDownload \
-H "Content-Type: application/json" \
-H "Range: bytes=$(stat -c%s movie.mp4)-" \
-d '{ "slug": "k3Jd9sLq2mXa7B", "file_index": 0 }' >> movie.mp4HTTP/1.1 206 Partial Content
Content-Range: bytes 52428800-734003199/734003200
Accept-Ranges: bytes
<binary>/functions/deleteTransferDelete a transfer
Requires an API Token. Only the owner can delete a transfer; it stops working immediately and frees up quota.
curl -X POST https://piggysend.com/functions/deleteTransfer \
-H "Content-Type: application/json" \
-H "X-Api-Key: ps_xxx" \
-d '{ "slug": "k3Jd9sLq2mXa7B" }'{ "ok": true }