Documentation menu

UPSCALR API

A REST API for image upscaling. Submit an image, track the job until it finishes, then download a result up to four times the size of the original.

Base URL

https://upscalr.app/api/v1

All endpoints are versioned under /v1 and served over HTTPS only. Requests and responses are JSON, except image upload (multipart form data) and image download (a redirect to the file).

How it works

Every upscale is an asynchronous job. You create one with a single request, and the API answers immediately with a job id while the work happens in the background. Most jobs finish within a few seconds. You can watch a job in two ways:

  • Poll: retrieve the job every second or two until its status is succeeded or failed.
  • Webhooks: register an endpoint and we POST to you the moment a job finishes. No polling loop to maintain.

When the job succeeds, download the result through a short-lived signed URL.

Your first request

One request creates a job. Keep your key in an environment variable. See API key setup.

curl -X POST https://upscalr.app/api/v1/upscale \
  -H "Authorization: Bearer $UPSCALR_API_KEY" \
  -F image=@photo.png \
  -F target=4k

Response · 202 Accepted

{
  "id": "cmrw0iqm8000bdcs3um6ii7fa",
  "object": "job",
  "status": "queued",
  "target": "4k",
  "credits": 3,
  "created_at": "2026-07-25T09:30:00Z"
}

The full walkthrough (polling, downloading, retries) is in the quickstart.

Endpoints

Each row links to its reference page with parameters, example requests in three languages, and every response code.

Authentication

Every request carries an API key as a bearer token. Keys start with usk_, are shown once at creation, and are managed from Dashboard → API keys. A missing or revoked key returns 401 unauthorized. Details are in API key setup.

curl https://upscalr.app/api/v1/jobs \
  -H "Authorization: Bearer $UPSCALR_API_KEY"

Output sizes

The target parameter picks the output size. Despite the k naming these are multipliers of the original: a 400×300 source with target=4k comes back at 1600×1200. Larger targets cost more credits.

ParameterTypeDescription
2k3 creditsTwice the original size. The default.
3k6 creditsThree times the original size.
4k9 creditsFour times the original size.

Not every image accepts every value. If the requested target is refused by the engine, we fall back to the largest it will take for that image, and the job reports the target actually used.

Supported inputs

ParameterTypeDescription
FormatsJPEG, PNG, WebP, AVIFDetected from the file bytes, not the declared content type.
Max file size10 MBLarger uploads are rejected with 413 payload_too_large.
Deliveryfile or URLSend the bytes as multipart form data, or JSON with a publicly reachable image_url.

Credits

Jobs are paid for in credits from your account balance, reserved on submit and refunded automatically if the job fails or is cancelled. You only pay for successful output. Every job response carries a credits field with the exact amount. Full rules in Pricing & credits.

Rate limits

Requests are limited per key, per minute: 60 by default, more on paid plans. Every response reports the window through X-RateLimit-* headers, and a 429 tells you exactly how long to wait via Retry-After. Details and backoff snippets in API limits.

Errors

Conventional HTTP status codes, and every error body carries a stable machine-readable error.code plus a human-readable message. Branch on the code, not the message. Every status and how to handle it is in the errors reference.

{
  "error": {
    "code": "insufficient_credits",
    "message": "This job needs 3 credits and you have 1."
  }
}

Idempotency

Send an Idempotency-Key header on submissions and retries become free: repeating a request with the same key returns the original job instead of creating and charging a second one. Use it anywhere your infrastructure might retry. Details are on the upscale reference.

Versioning

The version is in the path. Everything under /v1 keeps its current shape: we may add fields and endpoints, but existing fields will not change meaning or disappear. Breaking changes ship as /v2, and v1 keeps working.