All endpoints on this page require authentication via Authorization: Bearer <token>.
Avatar
Get avatar
GET /api/avatar
Returns the user’s avatar image. If the avatar is an external URL (e.g., from an OAuth provider), the response is a 302 redirect. Otherwise, the image binary is returned directly.
Response 200
Binary image data with appropriate Content-Type header (image/jpeg, image/png, image/webp, or image/gif).
Response 302
Redirect to external avatar URL (OAuth avatars).
Response 404
{
"message": "Avatar not found"
}
Upload avatar
POST /api/avatar
Uploads a new avatar image. The old avatar is automatically deleted.
Send the file as multipart/form-data with the field name avatar.
| Constraint | Value |
|---|
| Max file size | 2 MB |
| Allowed formats | JPEG, PNG, WebP, GIF |
Response 200
{
"avatar": "cuid_abc123/avatar_1717596600.png",
"message": "Avatar uploaded successfully"
}
Response 400
{
"message": "File too large. Maximum size is 2MB"
}
Delete avatar
DELETE /api/avatar
Removes the user’s avatar.
Response 200
{
"message": "Avatar deleted successfully"
}
Custom domain
Custom domains are only available on the enterprise tier for the DROP service.
Get custom domain
GET /api/user/custom-domain
Returns the current custom domain configuration.
Response 200
{
"customDomain": "files.example.com",
"customDomainVerified": true,
"hasCustomDomain": true
}
Response 403
{
"message": "Enterprise plan required for custom domains"
}
Set custom domain
POST /api/user/custom-domain
Connects a custom domain to the user’s DROP service. The domain starts as unverified - DNS configuration is required.
The custom domain to connect (e.g., files.example.com).
Response 200
{
"success": true,
"domain": "files.example.com",
"message": "Domain connected successfully. Please configure your DNS settings."
}
Response 409
{
"message": "Domain is already in use"
}
Delete custom domain
DELETE /api/user/custom-domain
Disconnects the custom domain.
Response 200
{
"success": true,
"message": "Custom domain disconnected successfully"
}
Services
List services
GET /api/services
Returns the user’s service entitlements. Optionally filter by service.
Filter by service identifier. Currently supported: DROP.
Response 200
{
"entitlements": [
{
"id": "ent_abc123",
"userId": "cuid_abc123",
"service": "DROP",
"tier": "pro",
"isPremium": true,
"connected": true,
"customStorageLimit": null,
"customApiKeyLimit": null,
"metadata": {},
"createdAt": "2026-01-15T10:30:00.000Z",
"updatedAt": "2026-06-05T14:30:00.000Z"
}
]
}
Update service
POST /api/services
Creates or updates a service entitlement for the current user.
Service identifier (e.g., DROP).
Service tier (e.g., free, pro-lite, pro, enterprise).
Whether the user has premium access.
Custom access flags for the service.
Arbitrary metadata for the service entitlement.
Custom storage limit override in bytes.
Custom API key limit override.
Response 200
{
"entitlement": {
"id": "ent_abc123",
"service": "DROP",
"tier": "pro",
"isPremium": true,
...
}
}
Subscription
Get subscription
GET /api/subscription
Returns the user’s current Polar subscription details for the DROP service. Prices are converted to PLN.
Response 200
{
"id": "sub_polar_123",
"status": "active",
"currentPeriodStart": 1717200000,
"currentPeriodEnd": 1719792000,
"cancelAtPeriodEnd": false,
"plan": "pro",
"billingCycle": "monthly",
"price": {
"amount": 39.96,
"currency": "pln",
"interval": "month"
},
"product": {
"name": "Premium"
}
}
Response 404
{
"message": "No active subscription"
}