EasySend API
Upload and share files programmatically. No API key required. Get a shareable link in one request.
Try it nowQuick Start
Upload a file and get a link. One command, under 60 seconds.
curl -F 'files[][email protected]' \
https://easysend.co/api/v1/upload
{
"success": true,
"short_code": "aB3xZ",
"share_url": "/aB3xZ",
"upload_token": "e4f9...64 hex chars",
"expires_at": "2026-03-29T12:00:00+00:00",
"files": [{
"id": 42,
"name": "photo.jpg",
"size": 284910,
"mime_type": "image/jpeg",
"download_url": "/api/v1/download/42"
}]
}
Share the file with anyone at https://easysend.co/aB3xZ -- the link is live immediately. Files expire in 3 days by default.
Endpoints
Upload one or more files and create a new bundle. Returns a share URL and an upload token you can use to add more files later.
Content-Type: multipart/form-data
| Parameter | Type | Description |
|---|---|---|
| files[]required | file(s) | One or more files. Repeat the field for multiple files. |
| encryptedoptional | string | Set to "1" to flag the bundle as client-side encrypted. |
{
"success": true,
"short_code": "aB3xZ",
"share_url": "/aB3xZ",
"upload_url": "/u/e4f9a1...64hex",
"upload_token": "e4f9a1...64hex",
"expires_at": "2026-03-29T12:00:00+00:00",
"files": [
{
"id": 42,
"name": "photo.jpg",
"size": 284910,
"mime_type": "image/jpeg",
"download_url": "/api/v1/download/42"
}
]
}
Add files to an existing bundle. Use the upload_token returned from the initial upload. The token is the 64-character hex string, passed as the URL path segment.
Content-Type: multipart/form-data
| Parameter | Type | Description |
|---|---|---|
| files[]required | file(s) | One or more files to add to the bundle. |
{
"success": true,
"short_code": "aB3xZ",
"share_url": "/aB3xZ",
"upload_url": "/u/e4f9a1...64hex",
"files": [
{
"id": 43,
"name": "readme.txt",
"size": 1024,
"mime_type": "text/plain",
"download_url": "/api/v1/download/43"
}
]
}
Retrieve full bundle metadata including all files, sizes, expiry, and encryption status. The short_code is the 5-character alphanumeric code from the share URL.
{
"success": true,
"short_code": "aB3xZ",
"file_count": 2,
"total_size_bytes": 285934,
"max_size_bytes": 1073741824,
"expires_at": "2026-03-29 12:00:00",
"is_expired": false,
"is_encrypted": false,
"created_at": "2026-03-26 12:00:00",
"files": [
{
"id": 42,
"name": "photo.jpg",
"size": 284910,
"mime_type": "image/jpeg",
"download_url": "/api/v1/download/42"
}
]
}
Lightweight status check. Returns expiry, size usage, and remaining space without the full file list. Useful for polling before adding more files.
{
"success": true,
"exists": true,
"is_expired": false,
"expires_at": "2026-03-29 12:00:00",
"total_size_bytes": 285934,
"max_size_bytes": 1073741824,
"space_remaining": 1073455890
}
Download a file by its numeric ID. Streams the raw file bytes with the appropriate Content-Type and Content-Disposition headers. Returns the file directly, not JSON.
Raw file stream with headers:
Content-Type: image/jpeg
Content-Disposition: attachment; filename="photo.jpg"
Content-Length: 284910
Delete a file from a bundle. Requires the upload_token for authorization. The file is permanently removed from storage.
Requires upload_token via Authorization: Bearer {token} header or ?upload_token={token} query parameter.
{
"success": true,
"deleted_file_id": 42
}
Code Examples
Complete working examples to upload a file and print the share URL.
#!/bin/bash
# Upload a file to EasySend
RESPONSE=$(curl -s -F 'files[][email protected]' \
https://easysend.co/api/v1/upload)
# Print the share URL
echo "$RESPONSE" | python3 -c \
"import sys,json; d=json.load(sys.stdin); print('https://easysend.co' + d['share_url'])"
# Upload more files to the same bundle
TOKEN=$(echo "$RESPONSE" | python3 -c \
"import sys,json; print(json.load(sys.stdin)['upload_token'])")
curl -s -F 'files[][email protected]' \
https://easysend.co/api/v1/upload/$TOKEN
import requests
# Upload a file
with open("photo.jpg", "rb") as f:
resp = requests.post(
"https://easysend.co/api/v1/upload",
files={"files[]": f}
)
data = resp.json()
print(f"Share URL: https://easysend.co{data['share_url']}")
# Add another file to the same bundle
token = data["upload_token"]
with open("readme.txt", "rb") as f:
requests.post(
f"https://easysend.co/api/v1/upload/{token}",
files={"files[]": f}
)
# Delete a file
file_id = data["files"][0]["id"]
requests.delete(
f"https://easysend.co/api/v1/file/{file_id}",
headers={"Authorization": f"Bearer {token}"}
)
// Upload a file using fetch
const form = new FormData();
form.append("files[]", fileInput.files[0]);
const resp = await fetch("https://easysend.co/api/v1/upload", {
method: "POST",
body: form,
});
const data = await resp.json();
console.log(`Share: https://easysend.co${data.share_url}`);
// Delete a file
await fetch(`https://easysend.co/api/v1/file/${data.files[0].id}`, {
method: "DELETE",
headers: {
"Authorization": `Bearer ${data.upload_token}`
},
});
<?php
// Upload a file using cURL
$ch = curl_init('https://easysend.co/api/v1/upload');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => [
'files[]' => new CURLFile('photo.jpg'),
],
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo "Share: https://easysend.co" . $data['share_url'] . "\n";
// Delete a file
$ch = curl_init("https://easysend.co/api/v1/file/" . $data['files'][0]['id']);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $data['upload_token'],
],
]);
curl_exec($ch);
curl_close($ch);
Try It
POST /api/v1/upload for real.
Authentication
Most endpoints require no authentication. You can upload files and retrieve bundles without any credentials.
The upload_token is returned when you create a bundle via POST /api/v1/upload. It acts as a bearer token that proves ownership of the bundle. You need it for:
-
POST /api/v1/upload/{upload_token}-- adding files (token is in the URL path) -
DELETE /api/v1/file/{file_id}-- deleting files (token via header or query)
Pass the token as an HTTP header or query parameter:
Authorization: Bearer e4f9a1b2c3d4e5f6...64 hex characters
DELETE /api/v1/file/42?upload_token=e4f9a1b2c3d4e5f6...64hex
Keep your upload_token secret. Anyone with this token can add or delete files in your bundle. There is no way to regenerate it.
Rate Limits
The API includes rate limit headers in every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
The current limit is 60 requests per minute per IP address. Rate limiting is not actively enforced yet, but the headers are included so you can design your integration around them. We reserve the right to enforce limits at any time.
If you need higher throughput for a specific use case, reach out and we will work with you.
Response Codes
All JSON responses include a "success": true|false field. Error responses also include an "error" message string.
| Code | Meaning | When |
|---|---|---|
| 200 | OK | Successful GET, DELETE, or append-upload request. |
| 201 | Created | New bundle created via POST /api/v1/upload. |
| 400 | Bad Request | Missing files, invalid format, size limit exceeded. |
| 401 | Unauthorized | Missing upload_token on endpoints that require it. |
| 403 | Forbidden | Invalid token, expired bundle, or access denied. |
| 404 | Not Found | Bundle or file does not exist, or has been deleted. |
| 500 | Server Error | Storage or database failure. Retry after a moment. |
Error response shape: {"success": false, "error": "Human-readable message"}
CLI Tool
Upload files from your terminal with a single command.
Install
curl -fsSL https://easysend.co/cli/install.sh | bash
Usage
# Upload a file
easysend photo.jpg
# Output: https://easysend.co/Ab3Kz
# Upload multiple files
easysend file1.pdf file2.png file3.zip
# Pipe from stdin
cat report.csv | easysend --name report.csv
# Copy link to clipboard
easysend photo.jpg --copy
# Get bundle info
easysend --info Ab3Kz
# Raw JSON output
easysend photo.jpg --json
Embed Widget
Add file uploads to any website with a single script tag. No API key needed.
Quick Start
<script src="https://easysend.co/widget/easysend-widget.js" data-theme="dark"></script>
<div id="easysend-upload"></div>
Options
data-theme="dark|light" - Color scheme (default: dark)
data-max-files="5" - Max files per upload (default: 10)
data-button-text="Upload" - Customize dropzone text
data-target="my-div" - Target div ID (default: easysend-upload)