Free to try. No account, no card

Turn Pixels into Perfection

Drop a photo in, or call the API. A cleaner version comes back in seconds.

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

targetaccepts2k3k4k

{
  "id": "cmrw0iqm8000bdcs3um6ii7fa",
  "object": "job",
  "status": "queued",
  "target": "4k",
  "filename": "photo.png",
  "credits": 3,
  "created_at": "2026-07-25T09:30:00Z"
}
Read the API docs
  • 2× – 4×on each dimension
  • PNG · JPEG · WebP · AVIFin and out
  • No accountfor the free tier
  • REST APIwith webhooks

Detail that was never in the original

Every pair below is genuine output from the same engine the uploader uses. The source was uploaded, upscaled and downloaded like any other job.

Pug, 360 × 240, before upscalingPug, 360 × 240, upscaled 4×Upscaled
Portraits4×
Pug, 360 × 240

Fur, fabric weave and eyelashes all collapse at 360px and come back strand by strand.

360 × 2401440 × 960

Portrait, 735 × 919, before upscalingPortrait, 735 × 919, upscaled 4×Upscaled
Portraits4×
Portrait, 735 × 919

Individual hairs, lash separation and skin texture survive the enlargement instead of smearing into one tone.

735 × 9192940 × 3676

Product shot, 300 × 300, before upscalingProduct shot, 300 × 300, upscaled 4×Upscaled
Products4×
Product shot, 300 × 300

A thumbnail-sized listing image, usable on a product page: edges hold and the surface keeps its grain.

300 × 3001200 × 1200

Scanned page, 389 × 280, before upscalingScanned page, 389 × 280, upscaled 4×Upscaled
Documents4×
Scanned page, 389 × 280

Letterforms come back sharp enough to read rather than guess — the case where softness costs you the content itself.

389 × 2801556 × 1120

Family photo, 1086 × 1448, before upscalingFamily photo, 1086 × 1448, upscaled 4×Upscaled
Old photos4×
Family photo, 1086 × 1448

A scan of a print: grain stays grain, and the detail already in the emulsion is resolved rather than invented.

1086 × 14484344 × 5792

Generated art, 760 × 1012, before upscalingGenerated art, 760 × 1012, upscaled 4×Upscaled
AI art4×
Generated art, 760 × 1012

Diffusion output at native size, taken to print resolution without the plastic smoothing an upscale usually adds.

760 × 10123040 × 4048

Logo mark, 378 × 450, before upscalingLogo mark, 378 × 450, upscaled 4×Upscaled
Logos4×
Logo mark, 378 × 450

Flat colour and hard edges — the case that exposes ringing and halos. The curves stay clean at four times the size.

378 × 4501512 × 1800

Building, 114 × 113, before upscalingBuilding, 114 × 113, upscaled 4×Upscaled
Architecture4×
Building, 114 × 113

The hardest source here, a 114px thumbnail: straight lines stay straight and the window grid survives.

114 × 113456 × 452

Wildlife, 399 × 501, before upscalingWildlife, 399 × 501, upscaled 4×Upscaled
Nature4×
Wildlife, 399 × 501

Fine repeating texture is where an upscale usually turns to mush: here the feather barbs and the catchlight hold.

399 × 5011596 × 2004

Inspect it at actual pixel size

Step the multiplier, then move the lens. The frame is the original stretched; the circle is the result at 1:1.

Output size1440 × 960
Original image, enlarged without upscalingOriginal, enlargedMove to inspect. Lens shows the upscale at 1:1

This is the real 4× output at 1440 × 960, straight from the engine. The lens shows it at 1:1; the surround is the 360px original stretched to match.

2× to 4× on each dimension. 4× is 16× the pixels.

What happens to your image

The same four states the API reports and the webhook fires on, not a diagram drawn for this page.

The file arrives01

Uploaded straight to storage with a presigned URL, so the image never passes through an application server that could become the bottleneck.

pending
Credits are reserved02

Reserved, not charged. The reservation is a guarded database write, so two concurrent jobs cannot both spend the last credit, and a failure releases it automatically.

queued
The engine runs03

Picked up by the worker loop and sent to the upscale engine. If the engine rejects the requested size for that image, the job retries at the largest size it will accept rather than failing.

processing
The result is yours04

Stored, converted to the format you asked for, and available over a signed download URL. The same moment fires your webhook, if you have one.

succeeded

Built for the images you already have

Not for generating new ones. For rescuing the ones that are already too small.

E-commerce

Product photography

Marketplace listings and supplier images arrive at whatever size the supplier had. Bring them up to what your own storefront expects, without a reshoot.

Restoration

Old photographs

Scans and phone snaps of prints lose the grain, the fabric and the eyelashes first. Those are exactly the details worth getting back.

Text

Documents and screenshots

Small type is where softness shows first. A larger, cleaner source is a better input to whatever reads it next.

300 DPI

Print

A web-sized image is fine on a screen and soft at 300 DPI. Upscaling before layout is cheaper than reshooting after proof.

Illustration

Game and concept art

Line work and flat colour survive enlargement badly. Clean edges matter more here than invented texture.

One POST, then a webhook

No SDK required, no polling if you don't want it, and a retried request never charges twice.

POSTupscalr.app/api/v1/upscale
curl -X POST https://upscalr.app/api/v1/upscale \
  -H "Authorization: Bearer $UPSCALR_API_KEY" \
  -F image=@photo.png \
  -F target=4k
Read the API docs
GET /v1/jobs/{id}sample
  1. queuedAccepted
  2. processingIn the engine
  3. succeededresult stored · webhook sent
{ "object": "job", "status": "succeeded" }
Job status succeeded

Everything starts with one image

Drop one in and see what comes back. No account, no card, no install.