Documentation
Everything you need to integrate img.in.net into your application.
Quick Start
Get up and running in three steps.
Get an API Key
Sign in at dream.img.in.net and create an API key from your dashboard.
Request a Presigned URL
curl -X POST https://dream.img.in.net/api/v1/upload/presign \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filename": "photo.jpg", "content_type": "image/jpeg", "size": 102400}' Response:
{
"upload_url": "https://dream.img.in.net/api/v1/upload/abc123...",
"file_uuid": "abc123-def456",
"token": "abc123...",
"expires_at": "2024-01-15T12:30:00Z",
"max_size": 52428800
} Upload the File
curl -X PUT "$UPLOAD_URL" \
-F "file=@photo.jpg;type=image/jpeg" That's it. The file is now processing. Configure a webhook URL to receive notifications when processing completes.
Authentication
All API requests require a Bearer token in the Authorization header:
Authorization: Bearer YOUR_API_KEY API keys are created in the dashboard. Each key can have its own webhook URL and processing settings.
Endpoints
/api/v1/upload/presign Request a presigned URL for direct browser upload.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| filename | string | Yes | Original filename (used for slug generation) |
| content_type | string | Yes | MIME type (image/jpeg, video/mp4, etc.) |
| size | integer | Yes | File size in bytes |
Response
| Field | Type | Description |
|---|---|---|
| upload_url | string | Presigned URL for PUT upload (valid 15 minutes) |
| file_uuid | string | Unique file identifier |
| token | string | Upload token (used in upload_url) |
| expires_at | string | ISO 8601 expiration timestamp |
| max_size | integer | Maximum allowed file size in bytes |
{upload_url} Upload file to the presigned URL using multipart form-data.
Response
{
"uuid": "abc123-def456",
"slug": "photo",
"content_type": "image/jpeg",
"size": 102400,
"status": "processing",
"url": "https://dream.img.in.net/abc123/photo.webp"
} /api/v1/files/{uuid} Get file metadata and variant URLs. Requires session authentication.
Response
{
"uuid": "abc123-def456",
"original_filename": "photo.jpg",
"slug": "photo",
"content_type": "image/jpeg",
"file_type": "image",
"size_bytes": 102400,
"width": 1920,
"height": 1080,
"status": "ready",
"url": "https://dream.img.in.net/abc123/photo.webp",
"variants": [
{
"variant_type": "thumb_150",
"width": 150,
"url": "https://dream.img.in.net/abc123/photo_150.webp"
},
{
"variant_type": "thumb_300",
"width": 300,
"url": "https://dream.img.in.net/abc123/photo_300.webp"
}
]
} Webhooks
When processing completes, we send a POST request to your configured webhook URL.
Success Payload
{
"event": "file.completed",
"file_uuid": "abc123-def456",
"status": "ready",
"timestamp": "2024-01-15T12:00:00Z",
"data": {
"uuid": "abc123-def456",
"original_filename": "photo.jpg",
"url": "https://dream.img.in.net/abc123/photo.webp",
"variants": {...}
}
} Failure Payload
{
"event": "file.failed",
"file_uuid": "abc123-def456",
"status": "failed",
"timestamp": "2024-01-15T12:00:00Z",
"data": {
"error_code": "PROCESSING_ERROR",
"error_message": "Details here"
}
} Headers
X-Webhook-Signature- HMAC-SHA256 signatureX-Webhook-Event- Event typeX-Webhook-Timestamp- Delivery timestamp
Signature Verification (Python)
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
if signature.startswith("sha256="):
signature = signature[7:]
expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature) Supported Formats
Images
| Input | Output |
|---|---|
| JPEG, PNG, GIF, HEIC, WebP | WebP (optimized) |
Thumbnails at 150px and 300px widths.
Videos
| Input | Output |
|---|---|
| MP4, MOV, WebM | H.264 MP4 |
Variants: 480p, 720p, 1080p. Poster frame extracted.
Rate Limits
| Tier | Requests/min | Storage | Processing |
|---|---|---|---|
| Free | 60 | 1 GB | 100 files/day |
| Pro | 300 | 100 GB | Unlimited |
Rate limit headers included in responses:
X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset
Error Codes
| Code | Description |
|---|---|
| 400 | Bad request (invalid parameters) |
| 401 | Unauthorized (invalid or missing API key) |
| 403 | Forbidden (API key lacks permission) |
| 404 | Not found |
| 413 | File too large |
| 415 | Unsupported media type |
| 429 | Rate limit exceeded |
| 500 | Server error |
Error responses include a JSON body:
{
"error": "invalid_content_type",
"message": "Content type 'application/pdf' is not supported"
} Code Examples
JavaScript / TypeScript
async function uploadImage(file, apiKey) {
// 1. Get presigned URL
const presignRes = await fetch('https://dream.img.in.net/api/v1/upload/presign', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
filename: file.name,
content_type: file.type,
size: file.size,
}),
});
const { upload_url, file_uuid } = await presignRes.json();
// 2. Upload file using multipart form-data
const formData = new FormData();
formData.append('file', file);
await fetch(upload_url, {
method: 'PUT',
body: formData,
});
return file_uuid;
} Python
import os
import requests
def upload_image(filepath: str, api_key: str) -> str:
filename = os.path.basename(filepath)
file_size = os.path.getsize(filepath)
# 1. Get presigned URL
presign_res = requests.post(
'https://dream.img.in.net/api/v1/upload/presign',
headers={'Authorization': f'Bearer {api_key}'},
json={
'filename': filename,
'content_type': 'image/jpeg',
'size': file_size,
},
)
data = presign_res.json()
# 2. Upload file using multipart form-data
with open(filepath, 'rb') as f:
requests.put(
data['upload_url'],
files={'file': (filename, f, 'image/jpeg')},
)
return data['file_uuid']