Reference

REST API

Upload files, create direct upload sessions, inspect share metadata, and download files without an SDK. This page documents the current public API surface.

Overview

The API is public and currently requires no user API key. Small files can be uploaded with a single multipart request. Larger files use a direct R2 upload session created by the service.

Inline

POST /api/upload accepts multipart/form-data with the file and delivery options.

Direct

POST /api/uploads creates a direct upload session, returns a presigned R2 upload URL, and is finalized with /complete.

Inline upload

Use the inline upload endpoint for smaller files. This is the simplest path and works well for scripts and small automation jobs.

Field Type Notes
file multipart file Required.
duration string One of 1h, 24h, 3d, 7d.
password string Optional. Protects downloads.
maxDownloads string/integer Optional. Positive integer, normalized up to 10,000.
notify repeated string Optional. Notification email addresses.

POST /api/upload

curl -X POST https://dlvr.sh/api/upload \
  -F "file=@./report.pdf" \
  -F "duration=24h" \
  -F "password=secret" \
  -F "maxDownloads=10" \
  -F "notify=team@example.com"

Success response

{
  "id": "a1c94e2f",
  "url": "https://dlvr.sh/f/a1c94e2f/",
  "expires": "2026-04-16T14:00:00.000Z",
  "downloads": 0,
  "maxDownloads": 10,
  "passwordRequired": true,
  "filename": "report.pdf",
  "size": 128044
}

Direct upload for larger files

Larger files use a session-based direct upload flow. First create a session, then upload the file to the provided R2 URL, then finalize the upload.

Deployment dependency

If direct upload signing is not configured on the deployment, POST /api/uploads returns 503.

1. Create upload session

curl -X POST https://dlvr.sh/api/uploads \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "artifact.zip",
    "contentType": "application/zip",
    "size": 104857600,
    "duration": "24h",
    "password": "secret",
    "maxDownloads": 5,
    "notifyEmails": ["team@example.com"]
  }'

2. Upload file to returned uploadUrl

curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: application/zip" \
  --data-binary "@./artifact.zip"

3. Finalize the upload

curl -X POST "https://dlvr.sh/api/uploads/$UPLOAD_ID/complete"

The session creation response includes uploadId, shareId, url, expiresAt, uploadUrl, and any headers required for the direct upload request.

Metadata and download

Use metadata endpoints when you need to inspect a file before downloading it or render your own client-side download experience.

GET /api/files/:id

curl https://dlvr.sh/api/files/a1c94e2f

GET /api/files/:id response

{
  "id": "a1c94e2f",
  "filename": "artifact.zip",
  "size": 10485760,
  "expires": "2026-04-16T14:00:00.000Z",
  "passwordRequired": false,
  "downloads": 0,
  "maxDownloads": null,
  "remainingDownloads": null,
  "expired": false
}

POST /api/files/:id/download

curl -X POST https://dlvr.sh/api/files/a1c94e2f/download \
  -F "password=secret" \
  -o artifact.zip

The download endpoint enforces password checks, expiry, and max-download rules before streaming the file.

Errors and status codes

Status Meaning
400 Missing file, bad JSON, unsupported duration, or malformed parameters.
401 Password required or incorrect.
404 Share or underlying object not found.
409 Direct upload incomplete, or download limit reached during claim.
410 File has expired.
413 File exceeds the inline or overall upload limit.
503 Direct upload is not configured on the deployment.