TiniDrop API Reference
The TiniDrop REST API lets you upload files, manage projects, retrieve per-file analytics, and register webhooks — all programmatically. Available on Solo and Pro plans.
Authentication
All API requests must be authenticated using an API key. Generate one from your dashboard under the API Keys tab. API access requires Solo or Pro plan.
Pass your key as the x-api-key header on every request:
curl https://tinidrop.com/api/me \
-H "x-api-key: td_YOUR_API_KEY"Keep your API key secret. Anyone with your key can upload, delete, and manage files on your account. Rotate it immediately if compromised.
/me
/api/meReturns the authenticated user's profile, plan details, and current usage.
curl https://tinidrop.com/api/me \
-H "x-api-key: td_YOUR_API_KEY"{
"id": "uuid",
"email": "you@example.com",
"plan": "pro",
"plan_name": "Pro",
"limits": {
"max_file_size_bytes": 10737418240,
"max_file_size_mb": 10240,
"max_storage_bytes": 10737418240,
"max_projects": 200,
"max_visits_per_month": 500000,
"expiry_days": null,
"features": {
"api_access": true,
"analytics": true,
"email_capture": true,
"disable_download": true,
"webhooks": true
}
},
"usage": {
"files": 12,
"storage_bytes": 52428800,
"storage_mb": 50,
"visits_this_month": 3421
}
}/files
/api/filesList all files for the authenticated user. Supports pagination and filtering.
Query Parameters
limitintegerMax results per page. Default: 50. Max: 200.
offsetintegerPagination offset. Default: 0.
projectstringFilter by project_id (UUID).
searchstringCase-insensitive file name search.
curl "https://tinidrop.com/api/files?limit=10&search=report" \
-H "x-api-key: td_YOUR_API_KEY"{
"files": [
{
"id": "uuid",
"slug": "my-report-2026",
"name": "Q1-report.pdf",
"url": "https://tinidrop.com/s/my-report-2026",
"size_bytes": 512000,
"visits": 142,
"created_at": "2026-01-15T10:30:00Z",
"expires_at": null,
"project_id": "uuid",
"project_name": "Client Reports",
"password_protected": false,
"email_capture": false,
"disable_download": false
}
],
"total": 1,
"limit": 10,
"offset": 0
}/api/uploadUpload a new file and receive a shareable link. Uses multipart/form-data.
Form Fields
fileFilerequiredThe file to upload. See supported formats below.
customSlugstringVanity URL slug (Solo+ only). E.g. my-portfolio
passwordstringPassword-protect this file (Solo+ only).
projectIdstringUUID of a project to attach this file to.
disableDownloadbooleanPrevent visitors from downloading the file (Solo+ only).
emailCapturebooleanRequire visitor email before access (Pro+ only).
feedbackbooleanEnable feedback widget on the viewer page (Starter+ only).
curl -X POST https://tinidrop.com/api/upload \
-H "x-api-key: td_YOUR_API_KEY" \
-F "file=@report.pdf" \
-F "customSlug=q1-report-2026" \
-F "disableDownload=true"{
"slug": "q1-report-2026",
"url": "https://tinidrop.com/s/q1-report-2026",
"original_name": "report.pdf",
"size_bytes": 512000,
"expires_at": null
}/api/files/{slug}Get metadata for a single file.
curl https://tinidrop.com/api/files/q1-report-2026 \
-H "x-api-key: td_YOUR_API_KEY"/api/files/{slug}Update file settings post-upload. All fields are optional.
Body (JSON)
namestringRename the file's display name.
passwordstringSet or change password. Pass empty string to remove.
disable_downloadbooleanToggle download disable (Solo+ only).
email_capturebooleanToggle email gate (Pro+ only).
feedbackbooleanToggle feedback widget (Starter+ only).
expires_atISO-8601 | nullSet or clear expiry. Pass null to make permanent.
slugstringRename the URL slug (Solo+ only, must be unique).
curl -X PATCH https://tinidrop.com/api/files/q1-report-2026 \
-H "x-api-key: td_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"disable_download": true, "slug": "q1-final"}'{
"success": true,
"slug": "q1-final",
"url": "https://tinidrop.com/s/q1-final"
}/api/uploadReplace an existing file's content while keeping the same URL. Pass the target slug as a form field.
fileFilerequiredNew file content.
slugstringrequiredSlug of the file to replace.
curl -X PUT https://tinidrop.com/api/upload \
-H "x-api-key: td_YOUR_API_KEY" \
-F "file=@report-v2.pdf" \
-F "slug=q1-final"/api/deletePermanently delete a file and remove it from storage.
curl -X DELETE https://tinidrop.com/api/delete \
-H "x-api-key: td_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"slug": "q1-final"}'{ "success": true }Supported file formats
/projects
/api/projectsList all projects.
curl https://tinidrop.com/api/projects \
-H "x-api-key: td_YOUR_API_KEY"{
"projects": [
{
"id": "uuid",
"name": "Client Reports",
"slug": "client-reports-xk2m1",
"created_at": "2026-01-01T00:00:00Z"
}
]
}/api/projectsCreate a new project.
namestringrequiredProject display name.
curl -X POST https://tinidrop.com/api/projects \
-H "x-api-key: td_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Client Reports"}'/api/projectsRename a project.
idstringrequiredProject UUID.
namestringrequiredNew project name.
curl -X PATCH https://tinidrop.com/api/projects \
-H "x-api-key: td_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": "uuid", "name": "Client Reports Q2"}'/api/move-to-projectMove a file into a project.
slugstringrequiredFile slug to move.
projectIdstringTarget project UUID. Pass null to remove from project.
curl -X POST https://tinidrop.com/api/move-to-project \
-H "x-api-key: td_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"slug": "q1-final", "projectId": "uuid"}'/api/projectsDelete a project. Files are unlinked but not deleted.
idstringrequiredProject UUID.
curl -X DELETE https://tinidrop.com/api/projects \
-H "x-api-key: td_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": "uuid"}'/analytics Unique feature
Per-file analytics via API. No other file hosting service exposes this. Use it to build dashboards, Zapier automations, Notion integrations, and more.
/api/analytics/{slug}Returns daily visit breakdown, referrer sources, and unique visitor counts.
daysintegerLookback window in days. Default: 30. Max: 365.
curl "https://tinidrop.com/api/analytics/q1-final?days=7" \
-H "x-api-key: td_YOUR_API_KEY"{
"slug": "q1-final",
"name": "report.pdf",
"total_visits": 1842,
"period_visits": 234,
"unique_visitors": 198,
"daily": [
{ "date": "2026-04-25", "visits": 45 },
{ "date": "2026-04-26", "visits": 31 }
],
"referrers": [
{ "source": "direct", "visits": 120 },
{ "source": "twitter.com", "visits": 64 },
{ "source": "notion.so", "visits": 50 }
],
"period_start": "2026-04-24T00:00:00.000Z",
"period_end": "2026-05-01T00:00:00.000Z",
"days": 7
}/webhooks
Register HTTPS endpoints to receive real-time notifications for TiniDrop events. Each delivery is signed with X-TiniDrop-Signature (HMAC-SHA256).
Available Events
/api/webhooksList all webhook registrations.
curl https://tinidrop.com/api/webhooks \
-H "x-api-key: td_YOUR_API_KEY"{
"webhooks": [
{
"id": "uuid",
"url": "https://your-server.com/hooks/tinidrop",
"events": ["file.uploaded", "email.captured"],
"is_active": true,
"created_at": "2026-01-01T00:00:00Z",
"last_triggered_at": "2026-04-30T12:00:00Z",
"failure_count": 0
}
]
}/api/webhooksRegister a new webhook endpoint.
urlstringrequiredPublic HTTPS URL that will receive POST requests.
eventsstring[]Events to subscribe to. Default: ["*"] (all events).
curl -X POST https://tinidrop.com/api/webhooks \
-H "x-api-key: td_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-server.com/hooks", "events": ["email.captured"]}'{
"webhook": {
"id": "uuid",
"url": "https://your-server.com/hooks",
"events": ["email.captured"],
"secret": "whsec_abc123...",
"is_active": true
}
}Verifying webhook signatures
// Node.js example
const crypto = require('crypto');
function verifySignature(secret, payload, sigHeader) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(sigHeader),
Buffer.from(expected)
);
}/api/webhooks/{id}Update a webhook's URL, events, or active status.
urlstringNew endpoint URL.
eventsstring[]Replace event subscriptions.
is_activebooleanPause (false) or resume (true) delivery.
curl -X PATCH https://tinidrop.com/api/webhooks/uuid \
-H "x-api-key: td_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"is_active": false}'/api/webhooks/{id}Remove a webhook registration.
curl -X DELETE https://tinidrop.com/api/webhooks/uuid \
-H "x-api-key: td_YOUR_API_KEY"Errors
All errors return a JSON body with an error string and a standard HTTP status code.
400Bad RequestMissing required field or invalid value.401UnauthorizedMissing or invalid x-api-key.403ForbiddenPlan does not include this feature, or resource belongs to another user.404Not FoundFile, project, or webhook not found.409ConflictSlug already taken (on upload or rename).413Payload Too LargeFile exceeds your plan limit.429Too Many RequestsRate limit or per-account limit reached.500Server ErrorInternal error — try again or contact support.Rate Limits
API requests are rate-limited per API key:
- Solo plan: 120 requests / minute, 5,000 uploads / day
- Pro plan: 600 requests / minute, 25,000 uploads / day
When a limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header indicating when to retry.