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. Both upload flows accept either a preset duration or a fixed ISO 8601 expiresAt value with an explicit timezone.
Current public upload policy
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 | Optional. One of 1h, 24h, 3d, 7d. Mutually exclusive with expiresAt. |
| expiresAt | string | Optional. Fixed expiry date in ISO 8601 format with an explicit timezone, for example 2026-04-25T18:00:00.000Z or 2026-04-25T20:00:00+02:00. Mutually exclusive with duration. |
| password | string | Optional. Protects downloads. |
| maxDownloads | string/integer | Optional. Positive integer, normalized up to 10,000. |
| notify | repeated string | Optional. Up to 3 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. The session request can include either duration or expiresAt.
Deployment dependency
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.
The direct-upload session endpoint enforces the same anonymous quota, recipient limit, and media policy before creating the session. Finalization re-checks the media policy before the share link becomes active.
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. |
| 415 | Upload blocked by media policy, including audio files and large anonymous videos. |
| 429 | Anonymous upload quota exceeded for the rolling 30-day window. |
| 503 | Direct upload is not configured on the deployment. |