DEVELOPER API Β· PUBLIC BETA

MegaPotato API

Upscale photos from your own code with the same model and the same chip prices as the site. Two requests: send a photo, then pick up the result.

On this page

Quickstart

Create a key on your account page, put it in the MEGAPOTATO_API_KEY environment variable, and run:

shell
# 1. Send a photo
curl https://megapotato.app/v1/upscale \
  -H "Authorization: Bearer $MEGAPOTATO_API_KEY" \
  -H "Idempotency-Key: photo-001" \
  -F [email protected] \
  -F upscale=4
# β†’ {"id": "6f6f4c1e-…", "status": "queued", "upscale": 4, "cost_chips": 8}

# 2. Wait for it (the server holds the request up to 55 s)
curl "https://megapotato.app/v1/jobs/6f6f4c1e-…?wait=55" \
  -H "Authorization: Bearer $MEGAPOTATO_API_KEY"
# β†’ {"status": "completed", "result_url": "https://…", …}

Test keys

Want to wire things up before buying chips? Any signed-in account can create a test key (mp_test_…) on the account page. It goes through the whole flow β€” uploads are checked and priced exactly like with a live key β€” but nothing runs and nothing is charged: every job comes back completed with a sample image. A retry with the same Idempotency-Key and photo returns the same job id; reusing a key for a different photo is only rejected (422) on live keys. Switch to a live key when you're ready; live keys unlock with your first chip pack.

Authentication

Send your key on every request in the Authorization header: Bearer mp_live_…. Keys are shown once when you create them; we store only a hash. Keep them on your server β€” never in a mobile app, a web page or a repository. If a key leaks, revoke it on your account page; it stops working immediately.

Check the price β€” POST /v1/quote

Send the input size and factor, get the price back. Nothing is uploaded or charged.

shell
curl https://megapotato.app/v1/quote \
  -H "Authorization: Bearer $MEGAPOTATO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"width": 4000, "height": 3000, "upscale": 2}'
# β†’ {"cost_chips": 21, "output_width": 8000, "output_height": 6000, "upscale": 2}

Upscale a photo β€” POST /v1/upscale

Multipart form with file (PNG, JPG, WEBP and HEIC, up to 40 MB) and upscale: 1 (refine, same size), 2, 4 or 8. The input can be up to 6Β 000 px on its long edge, and the result up to 16Β 400 px β€” pick a smaller factor for large photos.

response
{"id": "6f6f4c1e-…", "status": "queued", "upscale": 4, "cost_chips": 8}

cost_chips is held from your balance right away and charged when the photo is done. If processing fails, the chips come back automatically.

Get the result β€” GET /v1/jobs/{id}

Add ?wait=55 and the server holds the request until the job finishes or 55 seconds pass, whichever comes first β€” one call usually covers the whole job.

Most photos are back in seconds. When demand grows we bring more capacity online, and the first requests after that can take a couple of minutes β€” then everything runs at full speed. Keep polling with ?wait=55; there's nothing special to handle.

response
{
  "id": "6f6f4c1e-…",
  "status": "completed",          // queued β†’ running β†’ completed | failed
  "result_url": "https://…",      // PNG; a link valid for about an hour, no auth header needed
  "error": null,                  // the reason when failed, with "your chips were refunded"
  "upscale": 4,
  "created_at": "2026-09-15T10:00:00Z",
  "eta_seconds": null             // an estimate while queued or running
}

Fetch the job again for a fresh result_url. Results stay available for 90 days.

Errors

Every error has the same shape:

response
{"error": {"type": "insufficient_credits", "message": "insufficient chips: available 3, needed 8"}}
  • 400 Β· invalid_request_error
    The image can't be decoded, or its size is over the limits.
  • 401 Β· authentication_error
    The key is missing, wrong or revoked.
  • 402 Β· insufficient_credits
    Not enough chips for this photo β€” the message says how many are needed.
  • 404 Β· invalid_request_error
    No such job (or not yours).
  • 413 Β· invalid_request_error
    The file is larger than the upload limit.
  • 415 Β· invalid_request_error
    Unsupported image format.
  • 422 Β· invalid_request_error
    Bad upscale value, missing file, or an Idempotency-Key reused for a different photo.
  • 429 Β· rate_limit_error
    Too many requests, or too many photos in progress at once. Honor Retry-After.
  • 429 Β· spend_limit_reached
    Today's API spending limit is reached. Resets at 00:00 UTC.
  • 500 Β· server_error
    Our fault. Retry β€” with the same Idempotency-Key for uploads.

Limits

  • Up to 10 photos in progress at once per account. Past that, a new upload gets 429 and nothing is charged.
  • Up to 100 uploads per minute per key; status requests are more generous.
  • A daily spending limit through the API (UTC day), so a leaked key can't drain your balance β€” by default 5Β 000 chips a day. You can set a lower limit on your account page.

Pricing

The API costs exactly what the site costs for the same photo and factor, paid from the same chip balance. The price grows with the size of the result: a 1 MP photo at Γ—4 costs about 3 chips, a 12 MP phone photo at Γ—2 about 7 chips. Chips cost $0.033–0.05 each depending on the pack. Check any size with /v1/quote; a failed job is refunded automatically. Buy chips on the pricing page; they never expire.

Retries

  • Always send an Idempotency-Key (up to 128 characters, unique per photo) with uploads. Repeating the request with the same key returns the same job and charges once β€” so a timeout is always safe to retry.
  • On 429 wait for Retry-After. On 5xx or a network error, retry with a growing pause (1 s, 2 s, 4 s…). Other 4xx errors won't succeed on retry β€” fix the request.
  • Poll with ?wait=55 instead of calling every second.

Beta & versioning

The API is in public beta: there is no uptime guarantee yet, and we'll tell you by email about planned changes. Within /v1 we only add things β€” new fields, new error types β€” so ignore fields you don't know. Anything that would break an integration will ship as /v2, announced at least 90 days ahead.

Acceptable use

Results belong to you. Use the API only for images you have the right to process. It must not be used for illegal content, sexual content involving minors, or intimate images of anyone without their consent. Accounts that break these rules or the Terms are blocked. Report abuse to [email protected]; questions go to [email protected].

Get your API key