REST API
Build with FlingDrop
Upload files and generate shareable links from any application. Authenticate with a single API key, upload in one request or chunked, and let FlingDrop handle expiration and delivery.
Quick start
- 1
Create a free account
Sign up at app.flingdrop.com — it takes 30 seconds.
- 2
Get your API Key
Your API Key is emailed upon registration. You can also generate new keys from your dashboard under Settings > API Keys.
- 3
Upload your first file
Use the cURL command below to upload a file and get a shareable link.
curl -X POST https://app.flingdrop.com/api/upload \ -H "X-API-Key: YOUR_API_KEY" \ -F "file=@document.pdf"
Base URL & Authentication
All API requests go to:
https://app.flingdrop.comAuthenticate every request by including your API Key in the X-API-Key header:
X-API-Key: your_api_key_hereYour API Key is sent by email when you register. You can also create new keys from your dashboard.
Response format
All endpoints return JSON with a consistent shape:
Success response
{
"success": true,
"data": { ... }
}Error response
{
"success": false,
"error": {
"code": "INVALID_API_KEY",
"message": "..."
}
}Upload a file
POST /api/upload
Upload a single file using multipart form data. The server automatically detects duplicates by file hash — if the same file was already uploaded and has not expired, the existing URL is returned without storing a second copy.
Headers
| Header | Description | |
|---|---|---|
| X-API-Key | Required | Your API Key |
| X-Content-Encoding | Optional | Set to zstd if the file is zstd-compressed |
| X-Original-Size | Optional | Original size in bytes (required when using zstd) |
| X-File-Hash | Optional | SHA-256 hash of the original file (skips server-side recalculation) |
Body
multipart/form-data with a field named file.
Response
{
"success": true,
"data": {
"url": "https://app.flingdrop.com/f/abc123xyz",
"shortCode": "abc123xyz",
"fileName": "document.pdf",
"fileSize": 2048576,
"expiresAt": "2026-04-01T00:00:00Z",
"isDuplicate": false
}
}When isDuplicate is true, no new file was stored — the existing download link is returned.
Chunked upload
For large files, use chunked upload to split the transfer into multiple requests. This avoids timeouts and allows progress tracking.
Step 1 — Initialize session
POST /api/upload/init
Send file metadata to start a session. If a duplicate is detected by hash, the existing URL is returned immediately and no upload is needed.
JSON body
{
"fileName": "large-video.mp4",
"totalSize": 524288000,
"fileHash": "A1B2C3...",
"isCompressed": false,
"originalSize": 524288000
}Response
{
"success": true,
"data": {
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"isDuplicate": false
}
}Step 2 — Upload chunks
PATCH /api/upload/{sessionId}?index={n}
Send the raw bytes of each chunk in the request body (not multipart). Maximum 50 MB per chunk. The index query parameter is zero-based.
Response
{
"success": true,
"data": {
"bytesReceived": 10485760,
"chunksReceived": 1
}
}Step 3 — Complete upload
POST /api/upload/{sessionId}/complete
Reassembles the chunks, stores the final file, and creates the database record. Returns the same response shape as the simple upload endpoint.
Cancel upload
DELETE /api/upload/{sessionId}
Cancel an in-progress session and clean up temporary files.
Check duplicate
GET /api/check/{hash}
Check if a file with the given SHA-256 hash already exists in your tenant. Useful to avoid uploading a file that is already available.
Response
{
"success": true,
"data": {
"exists": true,
"url": "https://app.flingdrop.com/f/abc123xyz",
"expiresAt": "2026-04-01T00:00:00Z"
}
}When exists is false, url and expiresAt are null.
Download URLs
Every uploaded file gets a short URL in the format:
https://app.flingdrop.com/f/{shortCode}These URLs are public — no authentication is needed to download. Anyone with the link can download the file until it expires.
Expiration depends on the tenant plan: 7 days (Free), 30 days (Pro), or 90 days (Business). After expiration, the file is permanently deleted.
Health check
GET /api/status
Verify that the API is operational. No authentication required.
{
"success": true,
"data": {
"status": "OK",
"serverTime": "2026-03-23T12:00:00Z"
}
}Team invitations
Business plan onlyBusiness plan tenants can invite team members via the API. Invitations are sent by email and expire after 7 days.
Create invitation
POST /api/invitation
JSON body
{
"email": "colleague@company.com",
"role": "Member",
"tenantId": "550e8400-e29b-41d4-a716-446655440000"
}Response
{
"success": true,
"token": "...",
"invitationUrl": "https://app.flingdrop.com/invitation/...",
"message": "Invitation created successfully"
}Valid roles: Owner, Admin, Member, ReadOnly.
Get invitation info
GET /api/invitation/{token}
Retrieve the details of a pending invitation. No authentication required.
{
"success": true,
"tenantName": "Acme Corp",
"email": "colleague@company.com",
"role": "Member",
"expiresAt": "2026-03-30T00:00:00Z"
}Accept invitation
POST /api/invitation/{token}/accept
JSON body
{
"password": "securepassword123",
"name": "Jane Doe"
}If the email already has an account, only the membership is created. For new users, password (min 8 chars) is required.
Error codes
All error responses include a machine-readable code field:
| Code | HTTP Status | Description |
|---|---|---|
| INVALID_API_KEY | 401 | API key missing, invalid, or inactive |
| TENANT_INACTIVE | 401 | Tenant account is deactivated |
| INVALID_FILE | 400 / 413 / 429 | File validation failed (empty, too large, or limit reached) |
| FILE_TOO_LARGE | 413 | File exceeds plan size limit |
| STORAGE_LIMIT_EXCEEDED | 429 | Monthly storage cap exceeded |
| HASH_MISMATCH | 400 | File hash verification failed |
| INTERNAL_ERROR | 500 | Server-side error |
Rate limits
Upload endpoints are rate-limited. When you exceed the limit, you receive an HTTP 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait.
Implement exponential backoff in your client to handle rate limits gracefully.
Plan limits
Each plan has specific limits that the API enforces automatically:
| Limit | Free | Pro ($7/mo) | Business ($29/mo) |
|---|---|---|---|
| Max file size | 100 MB | 2 GB | 10 GB |
| Uploads per day | 5 | 100 | Unlimited |
| Link expiration | 7 days | 30 days | 90 days |
| Monthly transfer | No cap | No cap | 500 GB |
| Team members | 1 | 1 | 25 |
| API invitations | No | No | Yes |
Code examples
# Upload a file
curl -X POST https://app.flingdrop.com/api/upload \
-H "X-API-Key: YOUR_API_KEY" \
-F "file=@/path/to/document.pdf"# pip install requests
import requests
response = requests.post(
"https://app.flingdrop.com/api/upload",
headers={"X-API-Key": "YOUR_API_KEY"},
files={"file": open("document.pdf", "rb")},
)
data = response.json()
if data["success"]:
print(f"Download URL: {data['data']['url']}")
print(f"Expires at: {data['data']['expiresAt']}")
else:
print(f"Error: {data['error']['code']} — {data['error']['message']}")// Node.js (v18+) or browser
const form = new FormData();
form.append("file", fileInput.files[0]); // browser
// form.append("file", fs.createReadStream("document.pdf")); // Node.js
const res = await fetch("https://app.flingdrop.com/api/upload", {
method: "POST",
headers: { "X-API-Key": "YOUR_API_KEY" },
body: form,
});
const { success, data, error } = await res.json();
if (success) {
console.log("Download URL:", data.url);
console.log("Expires at:", data.expiresAt);
} else {
console.error(error.code, error.message);
}#!/bin/bash
# Upload all .log files from /var/log/myapp/
API_KEY="YOUR_API_KEY"
DIR="/var/log/myapp/"
for file in "$DIR"*.log; do
[ -f "$file" ] || continue
echo "Uploading $file..."
response=$(curl -s -X POST https://app.flingdrop.com/api/upload \
-H "X-API-Key: $API_KEY" \
-F "file=@$file")
url=$(echo "$response" | grep -o '"url":"[^"]*"' | cut -d'"' -f4)
echo " → $url"
doneReady to share?
Join thousands of users who already trust FlingDrop to share their files quickly and securely.