Your studio. In code.

Turn everyday product photos into polished images with a simple API.

API_BASEhttps://api.reimaginalo.com
  1. Upload an image

    Send a product photo with your preferred settings.

  2. Check the status

    Poll the returned ID to see when your image is ready.

  3. Download the result

    Retrieve your finished image from the provided URL.

Make your first request

One image. One request.
curl -X POST "$API_BASE/v1/generations" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: $REQUEST_KEY" \
  -F 'image=@shirt.jpg' \
  -F 'quality=low' \
  -F 'mode=default'

202 AcceptedPoll the returned ID to retrieve your image.

Set API_BASE, API_KEY, and a unique REQUEST_KEY. Reuse REQUEST_KEY when retrying this image.

Use a local file named shirt.jpg. Set API_BASE and API_KEY before running an example. Python requires requests; JavaScript requires Node.js 20+.

Authentication

Create a named key under Account → API keys and copy it once. Authenticate every request with a bearer token in the Authorization header.

Request header
Authorization: Bearer <api_key>
Your key stays on your server.

Keep keys out of browser code and source control. Each account supports five active keys, valid until revoked. Revocation blocks new requests immediately; accepted generations continue.

API access is available to all accounts. API keys cannot manage subscriptions or other keys.

Endpoints

Choose an endpoint to see everything needed to call it. Examples use API_BASE and API_KEY from the quickstart.

POST/v1/generationsGenerate an image

Generate an image

Upload one product photo. Returns a generation immediately; the image is processed asynchronously.

Inputs

Body: multipart/form-data. Let your HTTP client set Content-Type and its boundary. JSON and remote image URLs are not accepted.

FieldTypeDetails
Authorizationstring · headerRequired on every endpoint: Bearer <api_key>.
Idempotency-Keystring · headerOptional, recommended. 1–128 visible ASCII characters, no spaces. Reuse with identical file and settings to retry safely.
imagebinary · formRequired. One JPEG, PNG, WebP, HEIC or HEIF; ≤5 MiB, ≤25 megapixels, ≤12,000 pixels per edge.
qualitystring · formOptional. Default: low (1 credit); medium costs 1.5 credits; high costs 3 credits.
modestring · formOptional. Default: default (invisible mannequin). Other modes: wall_shadow (studio wall shadow), enhanced_original (polish the original presentation), subtle_movement (natural movement).
background_colorstring · formOptional. Default: #FFFFFF. Six-digit hex with or without #, normalized to uppercase #RRGGBB. Generated output is JPEG.

Request example

cURL
curl --request POST "$API_BASE/v1/generations" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: product-shirt-001" \
  -F 'image=@shirt.jpg' \
  -F 'quality=low' \
  -F 'mode=default' \
  -F 'background_color=#FFFFFF'

Response 202 Accepted · Generation

application/json · Illustrative example; IDs, dates and URLs will differ.

Response body
{
  "id": "ad7cc504-91d3-4b6e-b12f-624b967a8250",
  "status": "queued",
  "quality": "low",
  "mode": "default",
  "background_color": "#FFFFFF",
  "created_at": "2026-09-24T10:00:00Z",
  "completed_at": null,
  "output": null,
  "error": null
}
Response headers
Location: /v1/generations/ad7cc504-91d3-4b6e-b12f-624b967a8250
Retry-After: 3
Explore response fields & types
FieldTypeDetails
idstring · UUIDUnique attempt ID. Use this to poll, including for website regenerations.
statusstring · enumqueued | processing | completed | failed
qualitystring · enumlow | medium | high
modestring · enumdefault | wall_shadow | enhanced_original | subtle_movement
background_colorstringNormalized uppercase #RRGGBB.
created_atstring · date-timeCreation time in ISO 8601 format.
completed_atstring | nullCompletion time (ISO 8601), or null if not available.
outputobject | nullAvailable when the individual result is ready; null while pending, on failure, and in history.
output.urlstringTemporary download URL. Download without your API key.
output.expires_atstring · date-timeURL expiry (ISO 8601); one hour after retrieval.
output.content_typestringimage/jpeg
output.widthinteger | nullImage width in pixels, when available.
output.heightinteger | nullImage height in pixels, when available.
errorstring | nullFailure message when status is failed; otherwise null.

What happens behind the request

Credits are reserved on acceptance; failed attempts are refunded once. API and website generations share the same credit balance and image library, with your account’s usual availability and expiry rules. Processing continues after the response. Poll the returned ID every 3 seconds, backing off to 15 seconds. An identical idempotent retry returns the same attempt and its current status, even if already completed or failed.

Possible errors: 400 / 422 · 401 · 402 · 409 · 413 · 429 · 5xx. Error format & recovery →

GET/v1/generations/{generation_id}Check status & download

Check status & download

Read one attempt and get a fresh download URL when the image is ready.

Inputs

No request body or query parameters.

FieldTypeDetails
Authorizationstring · headerRequired on every endpoint: Bearer <api_key>.
generation_idstring · UUID · pathRequired. The id returned by creation or history. Must belong to your account.

Request example

cURL
curl "$API_BASE/v1/generations/ad7cc504-91d3-4b6e-b12f-624b967a8250" \
  -H "Authorization: Bearer $API_KEY"

Response 200 OK · Generation

application/json · Illustrative example; IDs, dates and URLs will differ.

Response body
{
  "id": "ad7cc504-91d3-4b6e-b12f-624b967a8250",
  "status": "completed",
  "quality": "low",
  "mode": "default",
  "background_color": "#FFFFFF",
  "created_at": "2026-09-24T10:00:00Z",
  "completed_at": "2026-09-24T10:00:30Z",
  "output": {
    "url": "https://storage.example.com/result.jpg?token=example",
    "expires_at": "2026-09-24T11:00:30Z",
    "content_type": "image/jpeg",
    "width": 1024,
    "height": 1536
  },
  "error": null
}
Explore response fields & types
FieldTypeDetails
idstring · UUIDUnique attempt ID. Use this to poll, including for website regenerations.
statusstring · enumqueued | processing | completed | failed
qualitystring · enumlow | medium | high
modestring · enumdefault | wall_shadow | enhanced_original | subtle_movement
background_colorstringNormalized uppercase #RRGGBB.
created_atstring · date-timeCreation time in ISO 8601 format.
completed_atstring | nullCompletion time (ISO 8601), or null if not available.
outputobject | nullAvailable when the individual result is ready; null while pending, on failure, and in history.
output.urlstringTemporary download URL. Download without your API key.
output.expires_atstring · date-timeURL expiry (ISO 8601); one hour after retrieval.
output.content_typestringimage/jpeg
output.widthinteger | nullImage width in pixels, when available.
output.heightinteger | nullImage height in pixels, when available.
errorstring | nullFailure message when status is failed; otherwise null.

What happens behind the request

Stop polling at completed or failed. Download output.url without an Authorization header; save the image to your own storage for permanent reuse. The link expires after one hour; call this endpoint again for a fresh one. A failed generation still returns HTTP 200 with status: failed and an error message.

Possible errors: 401 · 404 · 422 · 429 · 5xx. Error format & recovery →

GET/v1/generationsBrowse your history

Browse your history

List your account’s API and website attempts, newest first, in every state.

Inputs

No request body. Send pagination in the URL query string.

FieldTypeDetails
Authorizationstring · headerRequired on every endpoint: Bearer <api_key>.
limitinteger · queryOptional. 1–50; default 20.
offsetinteger · queryOptional. 0–10,000; default 0.

Request example

cURL
curl "$API_BASE/v1/generations?limit=20&offset=0" \
  -H "Authorization: Bearer $API_KEY"

Response 200 OK · GenerationPage

application/json · Illustrative example; IDs, dates and URLs will differ.

Response body
{
  "items": [
    {
      "id": "ad7cc504-91d3-4b6e-b12f-624b967a8250",
      "status": "completed",
      "quality": "low",
      "mode": "default",
      "background_color": "#FFFFFF",
      "created_at": "2026-09-24T10:00:00Z",
      "completed_at": "2026-09-24T10:00:30Z",
      "output": null,
      "error": null
    }
  ],
  "total": 1
}
Explore response fields & types
FieldTypeDetails
itemsGeneration[]Attempts on this page; an empty array when there are no results. Same fields as Generation, with output: null.
totalintegerTotal account attempts across all pages.
FieldTypeDetails
idstring · UUIDUnique attempt ID. Use this to poll, including for website regenerations.
statusstring · enumqueued | processing | completed | failed
qualitystring · enumlow | medium | high
modestring · enumdefault | wall_shadow | enhanced_original | subtle_movement
background_colorstringNormalized uppercase #RRGGBB.
created_atstring · date-timeCreation time in ISO 8601 format.
completed_atstring | nullCompletion time (ISO 8601), or null if not available.
outputobject | nullAvailable when the individual result is ready; null while pending, on failure, and in history.
output.urlstringTemporary download URL. Download without your API key.
output.expires_atstring · date-timeURL expiry (ISO 8601); one hour after retrieval.
output.content_typestringimage/jpeg
output.widthinteger | nullImage width in pixels, when available.
output.heightinteger | nullImage height in pixels, when available.
errorstring | nullFailure message when status is failed; otherwise null.

What happens behind the request

Increase offset by the number of items received to fetch the next page. Stop when items is empty or offset reaches total. New attempts can shift pages. All account keys can read this history. History never includes download URLs; fetch an individual generation for its output.

Possible errors: 401 · 422 · 429 · 5xx. Error format & recovery →

GET/v1/creditsCheck your balance

Check your balance

Read the credits currently available to your account, shared with the website.

Inputs

No request body, path parameters or query parameters.

FieldTypeDetails
Authorizationstring · headerRequired on every endpoint: Bearer <api_key>.

Request example

cURL
curl "$API_BASE/v1/credits" \
  -H "Authorization: Bearer $API_KEY"

Response 200 OK · Credits

application/json · Illustrative example; IDs, dates and URLs will differ.

Response body
{
  "credits_remaining": 12
}
Explore response fields & types
FieldTypeDetails
credits_remainingnumberAvailable balance. A JSON number, not necessarily an integer.

What happens behind the request

This is a snapshot, not a reservation. Other submissions can change the balance before your next request. Manage credits and subscriptions on the website.

Possible errors: 401 · 429 · 5xx. Error format & recovery →

The generation lifecycle

QueuedWaiting to startProcessingCreating your imageCompletedReady to downloadFailedCheck the error

Keep polling while queued or processing. completed → download the image. failed → read error; use a new idempotency key if you choose to submit again.

Errors & limits

100 image submissions and 500 reads per minute by default, shared across your account’s API keys. Each submission uploads one image; idempotent replays also count. On 429, wait the Retry-After seconds; on network errors or 5xx responses, use exponential backoff.

Retry without paying twice

Send a unique Idempotency-Key (1–128 visible ASCII characters, no spaces) per intended image. Persist it and reuse the same file and settings after a timeout. Identical retries return the same attempt and current status without another charge; changing the payload returns 409.

Idempotency keys are scoped to your account across API keys and the website, and retained with the generation record. Use a new key to intentionally generate another image, including after a failed attempt. After a local polling timeout, keep polling the same ID instead of submitting a replacement.

HTTPDescription
400 / 422Invalid file, settings, or request fields.
401Missing, invalid, or revoked API key.
402Insufficient credits. Manage your balance on the website.
404Generation missing or belongs to another account.
409Idempotency key already used with different input.
413Upload exceeds the file-size limit.
429Rate limit exceeded. Wait the Retry-After seconds.
5xxService error. Retry safely with exponential backoff.
Error response
{
  "error": {
    "code": "insufficient_credits",
    "message": "Not enough credits to generate this image",
    "request_id": "…"
  }
}

Error responses are JSON: error is an object with three string fields. code identifies the error category, message describes the problem, and request_id identifies the request for support. The X-Request-ID response header also carries this identifier. A 429 response includes Retry-After (seconds).

Include X-Request-ID when contacting support. v1 does not provide batches, webhooks, remote URL inputs, or regeneration endpoints.