API Documentation

Integrate AI-powered image upscaling into your applications with a simple REST API.

Quick Start

Upscale an image in three steps. Choose your language:

1

Get your API key

Sign up and subscribe to a paid plan to get your API key from the dashboard. Use it as a Bearer token in all requests:

Header
Authorization: Bearer YOUR_API_TOKEN
2

Upload an image for upscaling

curl -X POST https://www.upscale-media.ai/api/images/upscale \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "image=@photo.jpg" \
  -F "scale_factor=2"

# Returns 202 with image ID in data.id
response = requests.post(
    "https://www.upscale-media.ai/api/images/upscale",
    headers={"Authorization": f"Bearer {token}"},
    files={"image": open("photo.jpg", "rb")},
    data={"scale_factor": 2}
)
image_id = response.json()["data"]["id"]
const formData = new FormData();
formData.append("image", fileInput.files[0]);
formData.append("scale_factor", "2");

const upload = await fetch("https://www.upscale-media.ai/api/images/upscale", {
  method: "POST",
  headers: { "Authorization": `Bearer ${token}` },
  body: formData
});
const imageId = (await upload.json()).data.id;
$response = Http::withToken($token)
    ->attach('image', file_get_contents('photo.jpg'), 'photo.jpg')
    ->post('https://www.upscale-media.ai/api/images/upscale', [
        'scale_factor' => 2,
    ]);
$imageId = $response->json('data.id');
3

Poll until complete, then download

# Poll for completion
while true; do
  STATUS=$(curl -s https://www.upscale-media.ai/api/images/$IMAGE_ID \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    | jq -r '.data.status')
  echo "Status: $STATUS"
  [ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ] && break
  sleep 3
done

# Get the download URL
curl -s https://www.upscale-media.ai/api/images/$IMAGE_ID/download \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  | jq -r '.data.download_url'
import time

# Poll for completion
while True:
    result = requests.get(
        f"https://www.upscale-media.ai/api/images/{image_id}",
        headers={"Authorization": f"Bearer {token}"}
    ).json()
    status = result["data"]["status"]
    print(f"Status: {status}")
    if status in ("completed", "failed"):
        break
    time.sleep(3)

# Get the download URL
download = requests.get(
    f"https://www.upscale-media.ai/api/images/{image_id}/download",
    headers={"Authorization": f"Bearer {token}"}
).json()
print(download["data"]["download_url"])
// Poll for completion
const poll = async (id) => {
  while (true) {
    const res = await fetch(`https://www.upscale-media.ai/api/images/${id}`, {
      headers: { "Authorization": `Bearer ${token}` }
    });
    const { data } = await res.json();
    console.log(`Status: ${data.status}`);
    if (data.status === "completed" || data.status === "failed") {
      return data;
    }
    await new Promise(r => setTimeout(r, 3000));
  }
};

const image = await poll(imageId);

// Get the download URL
const dl = await fetch(`https://www.upscale-media.ai/api/images/${imageId}/download`, {
  headers: { "Authorization": `Bearer ${token}` }
});
const { data: dlData } = await dl.json();
console.log(dlData.download_url);
// Poll for completion
do {
    sleep(3);
    $result = Http::withToken($token)
        ->get("https://www.upscale-media.ai/api/images/{$imageId}")
        ->json();
    $status = $result['data']['status'];
    echo "Status: {$status}\n";
} while (!in_array($status, ['completed', 'failed']));

// Get the download URL
$download = Http::withToken($token)
    ->get("https://www.upscale-media.ai/api/images/{$imageId}/download")
    ->json();
echo $download['data']['download_url'];

Overview

The Upscale Media API lets you integrate AI-powered image upscaling into your applications. Upload images, poll for results, and download enhanced versions — all via simple REST endpoints.

Base URL
https://www.upscale-media.ai/api

Response Format

All responses return JSON with a consistent envelope:

JSON
{
  "success": true,
  "message": "Human-readable status message",
  "data": { ... }
}

Error responses include success: false and may include an errors object for validation failures.

Authentication

Authenticate by including a Bearer token in the Authorization header. Obtain a token by registering or logging in via the API, or from your dashboard after signing up.

Header
Authorization: Bearer YOUR_API_TOKEN
POST /api/auth/register Public

Create a new account and receive a Bearer token. A verification email is sent automatically.

Body Parameters

Parameter Type Required Description
name string Yes Full name (max 255 characters)
email string Yes Valid email address (unique)
password string Yes Min 8 characters, mixed case, numbers
password_confirmation string Yes Must match password
device_name string No Label for the token (defaults to user agent)
Response · 201 Created
{
  "success": true,
  "message": "Registration successful. Please verify your email to access all features.",
  "data": {
    "user": {
      "id": 1,
      "name": "Jane Smith",
      "email": "jane@example.com",
      "email_verified_at": null,
      "profile_photo_url": "https://...",
      "created_at": "2026-02-15T12:00:00.000000Z",
      "updated_at": "2026-02-15T12:00:00.000000Z",
      "pricing_plan": {
        "id": 1,
        "name": "Free",
        "slug": "free"
      }
    },
    "token": "1|abc123...",
    "token_type": "Bearer"
  }
}
POST /api/auth/login Public

Authenticate with email and password. Returns a Bearer token. Requires a verified email address.

Request
curl -X POST https://www.upscale-media.ai/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "jane@example.com", "password": "your-password"}'
Response · 200 OK
{
  "success": true,
  "message": "Login successful",
  "data": {
    "user": { ... },
    "token": "2|xyz789...",
    "token_type": "Bearer"
  }
}
POST /api/auth/logout Authenticated

Revoke the current API token.

Response · 200 OK
{"success": true, "message": "Logout successful"}
POST /api/auth/revoke-all Authenticated

Revoke all API tokens for your account. Use this if a token is compromised.

Response · 200 OK
{"success": true, "message": "All tokens revoked successfully"}

Images

Upload images for AI upscaling, check processing status, and download enhanced results. Upscaling is asynchronous — submit an image, then poll for completion.

POST /api/images/upscale Authenticated

Submit an image for upscaling. Returns immediately with a 202 Accepted status while processing happens in the background.

Body Parameters (multipart/form-data)

Parameter Type Required Description
image file Yes JPEG, PNG, WebP, BMP, TIFF, or GIF. Max 10MB.
scale_factor integer No 2, 3, or 4. Defaults to 2. Cannot be used with target_width/target_height.
target_width integer No Exact output width in pixels (1–16384). If target_height is omitted, it is calculated automatically to preserve aspect ratio. Cannot be used with scale_factor.
target_height integer No Exact output height in pixels (1–16384). If target_width is omitted, it is calculated automatically to preserve aspect ratio. Cannot be used with scale_factor.

Sizing options: Use scale_factor for simple 2x/3x/4x upscaling, or specify a target resolution. You can provide both target_width and target_height for exact dimensions, or just one — the other will be calculated automatically to preserve the original aspect ratio. The target must be larger than the original and achievable within your plan's max scale (e.g., 4x).

Request
curl -X POST https://www.upscale-media.ai/api/images/upscale \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "image=@photo.jpg" \
  -F "scale_factor=2"
import requests

response = requests.post(
    "https://www.upscale-media.ai/api/images/upscale",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"},
    files={"image": open("photo.jpg", "rb")},
    data={"scale_factor": 2}
)
print(response.json())
const formData = new FormData();
formData.append("image", fileInput.files[0]);
formData.append("scale_factor", "2");

const response = await fetch("https://www.upscale-media.ai/api/images/upscale", {
  method: "POST",
  headers: { "Authorization": "Bearer YOUR_API_TOKEN" },
  body: formData
});
const data = await response.json();
$response = Http::withToken('YOUR_API_TOKEN')
    ->attach('image', file_get_contents('photo.jpg'), 'photo.jpg')
    ->post('https://www.upscale-media.ai/api/images/upscale', [
        'scale_factor' => 2,
    ]);
$data = $response->json();
Response · 202 Accepted
{
  "success": true,
  "message": "Image uploaded and queued for processing",
  "data": {
    "id": 42,
    "original_filename": "photo.jpg",
    "original_size": 2048576,
    "original_size_human": "2 MB",
    "original_dimensions": null,
    "status": "pending",
    "scale_factor": 2,
    "target_width": null,
    "target_height": null,
    "api_request": true,
    "created_at": "2026-02-15T12:00:00.000000Z",
    "updated_at": "2026-02-15T12:00:00.000000Z"
  }
}

Tip: After uploading, poll GET /api/images/{id} every few seconds until status is completed or failed.

GET /api/images/{id} Authenticated

Get the status and details of a specific image. Use this to poll for processing completion.

Request
curl https://www.upscale-media.ai/api/images/42 \
  -H "Authorization: Bearer YOUR_API_TOKEN"
response = requests.get(
    "https://www.upscale-media.ai/api/images/42",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"}
)
print(response.json())
const response = await fetch("https://www.upscale-media.ai/api/images/42", {
  headers: { "Authorization": "Bearer YOUR_API_TOKEN" }
});
const data = await response.json();
$response = Http::withToken('YOUR_API_TOKEN')
    ->get('https://www.upscale-media.ai/api/images/42');
$data = $response->json();
Response · 200 OK (completed)
{
  "success": true,
  "message": "Image retrieved successfully",
  "data": {
    "id": 42,
    "original_filename": "photo.jpg",
    "original_path": "images/originals/abc123.jpg",
    "upscaled_path": "images/upscaled/abc123.jpg",
    "original_size": 2048576,
    "upscaled_size": 8194304,
    "original_size_human": "2 MB",
    "upscaled_size_human": "7.81 MB",
    "original_dimensions": "1920x1080",
    "upscaled_dimensions": "3840x2160",
    "original_dimensions_formatted": "1920 x 1080",
    "upscaled_dimensions_formatted": "3840 x 2160",
    "status": "completed",
    "scale_factor": 2,
    "target_width": null,
    "target_height": null,
    "processing_time": 4.82,
    "api_request": true,
    "download_url": "https://...",
    "created_at": "2026-02-15T12:00:00.000000Z",
    "updated_at": "2026-02-15T12:00:05.000000Z"
  }
}

Image Statuses

pending processing completed failed
GET /api/images Authenticated

List all your images with pagination. Newest first.

Query Parameters

Parameter Type Default Description
page integer 1 Page number
per_page integer 15 Items per page (max 100)
status string all Filter: pending, processing, completed, or failed
Request
curl "https://www.upscale-media.ai/api/images?per_page=10&status=completed" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
Response · 200 OK
{
  "success": true,
  "message": "Images retrieved successfully",
  "data": [ { ... }, { ... } ],
  "meta": {
    "current_page": 1,
    "last_page": 3,
    "per_page": 10,
    "total": 27
  },
  "links": {
    "first": "https://www.upscale-media.ai/api/images?page=1",
    "last": "https://www.upscale-media.ai/api/images?page=3",
    "prev": null,
    "next": "https://www.upscale-media.ai/api/images?page=2"
  }
}
GET /api/images/{id}/download Authenticated

Get a download URL for a completed image. Returns an error if the image is still processing.

Response · 200 OK
{
  "success": true,
  "message": "Download URL generated successfully",
  "data": {
    "download_url": "https://...",
    "filename": "photo.jpg"
  }
}
DELETE /api/images/{id} Authenticated

Permanently delete an image and its upscaled version.

Response · 200 OK
{"success": true, "message": "Image deleted successfully"}

Batches

Upload multiple images at once for batch upscaling. Each image is processed independently and you can track overall batch progress.

Batch processing requires a Professional or Enterprise plan. Each image in a batch counts toward your monthly quota.
POST /api/batches Authenticated · Pro/Enterprise

Upload up to 20 images in a single request. Returns immediately with a 202 Accepted status while all images are queued for processing.

Body Parameters (multipart/form-data)

Parameter Type Required Description
images[] file[] Yes 1-20 image files. JPEG, PNG, WebP, BMP, TIFF, or GIF. Max 10MB per file.
scale_factor integer No 2, 3, or 4. Applied to all images. Defaults to 2. Cannot be used with target dimensions.
target_width integer No Exact output width in pixels (1–16384). Applied to all images. If target_height is omitted, aspect ratio is preserved.
target_height integer No Exact output height in pixels (1–16384). Applied to all images. If target_width is omitted, aspect ratio is preserved.
name string No Optional label for this batch (max 255 characters).
Request
curl -X POST https://www.upscale-media.ai/api/batches \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "images[]=@photo1.jpg" \
  -F "images[]=@photo2.jpg" \
  -F "images[]=@photo3.jpg" \
  -F "scale_factor=2" \
  -F "name=Product photos"
Response · 202 Accepted
{
  "success": true,
  "message": "Batch created and images queued for processing",
  "data": {
    "id": 7,
    "name": "Product photos",
    "status": "pending",
    "total_images": 3,
    "completed_images": 0,
    "failed_images": 0,
    "scale_factor": 2,
    "progress": 0,
    "images": [
      { "id": 101, "batch_id": 7, "original_filename": "photo1.jpg", "status": "pending", ... },
      { "id": 102, "batch_id": 7, "original_filename": "photo2.jpg", "status": "pending", ... },
      { "id": 103, "batch_id": 7, "original_filename": "photo3.jpg", "status": "pending", ... }
    ],
    "created_at": "2026-02-15T12:00:00.000000Z",
    "updated_at": "2026-02-15T12:00:00.000000Z",
    "completed_at": null
  }
}

Tip: Poll GET /api/batches/{id} to track overall progress. The progress field shows completion percentage. All images must fit within your remaining monthly quota.

GET /api/batches/{id} Authenticated · Pro/Enterprise

Get the status and details of a batch, including all its images. Use this to poll for batch completion.

Request
curl https://www.upscale-media.ai/api/batches/7 \
  -H "Authorization: Bearer YOUR_API_TOKEN"
Response · 200 OK (completed)
{
  "success": true,
  "message": "Batch retrieved successfully",
  "data": {
    "id": 7,
    "name": "Product photos",
    "status": "completed",
    "total_images": 3,
    "completed_images": 3,
    "failed_images": 0,
    "scale_factor": 2,
    "progress": 100,
    "images": [
      { "id": 101, "status": "completed", "download_url": "https://...", ... },
      { "id": 102, "status": "completed", "download_url": "https://...", ... },
      { "id": 103, "status": "completed", "download_url": "https://...", ... }
    ],
    "created_at": "2026-02-15T12:00:00.000000Z",
    "updated_at": "2026-02-15T12:00:05.000000Z",
    "completed_at": "2026-02-15T12:00:05.000000Z"
  }
}

Batch Statuses

pending processing completed partially_failed failed cancelled
GET /api/batches Authenticated · Pro/Enterprise

List all your batches with pagination. Newest first.

Query Parameters

Parameter Type Default Description
page integer 1 Page number
per_page integer 15 Items per page (max 100)
status string all Filter: pending, processing, completed, partially_failed, failed, or cancelled
Response · 200 OK
{
  "success": true,
  "message": "Batches retrieved successfully",
  "data": [ { ... }, { ... } ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 15,
    "total": 2
  },
  "links": { ... }
}
DELETE /api/batches/{id} Authenticated · Pro/Enterprise

Cancel a pending/processing batch or permanently delete a completed batch. Cancelling marks unfinished images as failed.

Response · 200 OK
{"success": true, "message": "Batch cancelled successfully"}

Account

Manage your profile, check usage quotas, and view subscription details.

GET /api/user Authenticated

Get the authenticated user's profile and current plan.

Response · 200 OK
{
  "success": true,
  "message": "User retrieved successfully",
  "data": {
    "id": 1,
    "name": "Jane Smith",
    "email": "jane@example.com",
    "email_verified_at": "2026-02-15T12:05:00.000000Z",
    "profile_photo_url": "https://...",
    "created_at": "2026-02-15T12:00:00.000000Z",
    "updated_at": "2026-02-15T12:00:00.000000Z",
    "pricing_plan": {
      "id": 2,
      "name": "Starter",
      "slug": "starter"
    }
  }
}
GET /api/usage Authenticated

Check your current month's usage against your plan quota.

Response · 200 OK
{
  "success": true,
  "message": "Usage statistics retrieved successfully",
  "data": {
    "plan": "starter",
    "image_uploads": {
      "used": 42,
      "limit": 100,
      "remaining": 58,
      "unlimited": false,
      "exceeded": false,
      "percentage": 42.0
    },
    "features": ["api_access", "priority_support"]
  }
}
GET /api/subscription Authenticated

Get your current subscription status and plan details.

Response · 200 OK
{
  "success": true,
  "message": "Subscription details retrieved successfully",
  "data": {
    "subscription": {
      "id": 1,
      "type": "default",
      "status": "active",
      "quantity": 1,
      "trial_ends_at": null,
      "ends_at": null,
      "created_at": "2026-01-01T00:00:00.000000Z",
      "is_active": true,
      "is_on_trial": false,
      "is_cancelled": false,
      "is_on_grace_period": false
    },
    "plan": {
      "name": "Starter",
      "slug": "starter",
      "price": 9,
      "features": [...],
      "limits": [...]
    }
  }
}
GET /api/user/tokens Authenticated

List all your active API tokens.

Response · 200 OK
{
  "success": true,
  "message": "API tokens retrieved successfully",
  "data": {
    "tokens": [
      {
        "id": 1,
        "name": "My App",
        "abilities": ["images:read", "images:write", "images:delete", "user:read"],
        "last_used_at": "2026-02-15T11:30:00.000000Z",
        "created_at": "2026-01-15T09:00:00.000000Z"
      }
    ],
    "count": 1
  }
}
DELETE /api/user/tokens/{id} Authenticated

Revoke a specific API token by its ID.

Response · 200 OK
{"success": true, "message": "Token revoked successfully"}

Rate Limits

API requests are rate-limited based on your plan. Limits reset every hour.

Plan Requests / Hour Images / Month
Unauthenticated 10
Free 100 2
Starter 500 25
Professional 2,000 250
Enterprise 10,000 1,000 – 12,500

Rate Limit Headers

Image endpoints include headers to help you track your upload quota:

Header Description
X-RateLimit-Limit Your plan's monthly image quota
X-RateLimit-Remaining Remaining image uploads this month

Errors

The API uses standard HTTP status codes. Errors return a consistent JSON structure.

Error Response
{
  "success": false,
  "message": "Validation failed",
  "errors": {
    "image": ["The image field is required."],
    "scale_factor": ["The scale factor must be between 2 and 4."]
  }
}
Code Status Description
400 Bad Request The request was malformed or image processing failed
401 Unauthorized Missing or invalid Bearer token
403 Forbidden Email not verified, no API access on plan, subscription expired, or quota exceeded
404 Not Found Image or token not found
422 Validation Error Invalid input. Check the errors object for field-specific messages.
429 Too Many Requests Rate limit exceeded. Slow down or upgrade your plan.
500 Server Error Something went wrong on our end. Try again later.