API Reference

Documentation

Everything you need to integrate img.in.net into your application.

Quick Start

Get up and running in three steps.

1

Get an API Key

Sign in at dream.img.in.net and create an API key from your dashboard.

2

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
}
3

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

POST /api/v1/upload/presign

Request a presigned URL for direct browser upload.

Request Body

Field Type Required Description
filenamestringYesOriginal filename (used for slug generation)
content_typestringYesMIME type (image/jpeg, video/mp4, etc.)
sizeintegerYesFile size in bytes

Response

Field Type Description
upload_urlstringPresigned URL for PUT upload (valid 15 minutes)
file_uuidstringUnique file identifier
tokenstringUpload token (used in upload_url)
expires_atstringISO 8601 expiration timestamp
max_sizeintegerMaximum allowed file size in bytes
PUT {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"
}
GET /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 signature
  • X-Webhook-Event - Event type
  • X-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, WebPWebP (optimized)

Thumbnails at 150px and 300px widths.

Videos

Input Output
MP4, MOV, WebMH.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-Limit
  • X-RateLimit-Remaining
  • X-RateLimit-Reset

Error Codes

Code Description
400Bad request (invalid parameters)
401Unauthorized (invalid or missing API key)
403Forbidden (API key lacks permission)
404Not found
413File too large
415Unsupported media type
429Rate limit exceeded
500Server 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']