API Docs
Upload media, list uploads, and manage files with bearer-token auth.
Authentication
Create an API key from the app, then pass it as a bearer token on every request.
Authorization: Bearer ih_your_api_key
Upload Media
Uploads use multipart form data. The file field must be named image.
curl -H "Authorization: Bearer ih_your_api_key" \
-F "image=@photo.png" \
http://localhost:3000/api/upload
{
"image": {
"id": "abc123",
"originalName": "photo.png",
"size": 204800,
"mimeType": "image/png",
"createdAt": "2026-05-24T18:30:00.000Z",
"expiresAt": "2026-05-27T18:30:00.000Z",
"url": "/i/abc123"
},
"url": "/i/abc123",
"expiresAt": "2026-05-27T18:30:00.000Z"
}
List Images
curl -H "Authorization: Bearer ih_your_api_key" \
http://localhost:3000/api/images
Delete Image
curl -X DELETE \
-H "Authorization: Bearer ih_your_api_key" \
http://localhost:3000/api/images/IMAGE_ID
My Invites
Returns unused invite codes assigned to the authenticated user.
GET /api/my-invites
{
"invites": [
{
"code": "PIH-AbC123xYz789LmNo",
"createdAt": "2026-05-24T18:30:00.000Z"
}
]
}
Public Image URL
Image URLs do not require auth and expire after 3 days.
GET /i/IMAGE_ID
Rate Limits
| Area | Limit | Scope |
|---|---|---|
| Standard upload size | 750 MB per file | Each upload |
| Promoted upload size | 1 GB per file | Promoted accounts |
| Supported formats | PNG, JPEG, GIF, WebP, AVIF, MP4, WebM, MOV, M4V | Each upload |
| Concurrent uploads | 3 at once | Per account |
| Upload count | 60 per 10 minutes | Per account |
| Upload volume | 10 GB per hour | Per account |
| API calls | 300 per 10 minutes | Per account |
| Login / register | 5 attempts per 15 minutes | Per IP address |
| Public image views | 1 000 per 10 minutes | Per IP address |
| Invite creation | 20 per hour | Per admin account |
| Promoted accounts | No authenticated rate limits | Promoted account |
Admin Endpoints
Admin endpoints require an admin browser session and are intended for the web admin panel.
GET /api/admin/users
POST /api/admin/users/USER_ID/ban
Content-Type: application/json
{ "banned": true }
POST /api/admin/users/USER_ID/promote
Content-Type: application/json
{ "promoted": true }
POST /api/admin/users/USER_ID/invites
Invite codes use the PIH- prefix followed by 16 random characters.
Rate Limit Response
When a limit is exceeded the API returns HTTP 429 with a Retry-After header.
{
"error": "Rate limit exceeded.",
"limit": 60,
"remaining": 0,
"retryAfter": 120,
"windowSeconds": 600
}