# Enhance an image

> Upscale, add detail, remove a background or extend the frame.

Source: https://developers.mnml.ai/docs/enhancements

`POST https://api.mnml.ai/v2/enhancements`

## Example request

**curl**

```bash
curl -X POST https://api.mnml.ai/v2/enhancements \
  -H "Authorization: Bearer $MNML_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "upscale",
    "job_id": "10482"
  }'
```

**TypeScript**

```ts
const res = await fetch("https://api.mnml.ai/v2/enhancements", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MNML_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "kind": "upscale",
    "job_id": "10482"
  }),
});

const data = await res.json();
```

**Python**

```python
import os, requests

res = requests.post(
    "https://api.mnml.ai/v2/enhancements",
    headers={"Authorization": f"Bearer {os.environ['MNML_API_KEY']}"},
    json={
      "kind": "upscale",
      "job_id": "10482"
    },
)

data = res.json()
```

## Example response (202)

```json
{
  "success": true,
  "data": {
    "id": "10484",
    "status": "queued",
    "charged_usd": 0.0198,
    "credits_charged": 2,
    "replayed": false,
    "notes": []
  }
}
```

Returns `202` straight away with the job and what it charged. Poll [GET /v2/jobs/{id}](https://developers.mnml.ai/docs/jobs) for the result; a job that fails is refunded.

> [!WARNING]
> `upscale`, `enhance` and `outpaint` need an account that has topped up its API wallet. On an account that never has, they return `403 PLAN_REQUIRED` and nothing is charged.

| Kind | Does | Price |
| --- | --- | --- |
| upscale | Enlarge a finished render for print and presentation boards. | $0.0198 per image |
| enhance | Add detail and realism to an existing render. | $0.297 per image |
| bg-remove | Cut a building or product out onto a transparent background. | $0.0297 per image |
| outpaint | Widen the frame beyond the original image. | $0.0594 per image |

## Headers

- `Authorization` (string, required): `Bearer mk_live_…`: your API key. See [Authentication](https://developers.mnml.ai/docs/authentication).
- `Content-Type` (string, required): `application/json`, or `multipart/form-data` to send a file.
- `Idempotency-Key` (string): Your own key, 1 to 255 visible ASCII characters. A retry with the same key and request within 24 hours returns the first answer instead of running again.

## Body

- `kind` (string, required): What to do to the image. Values: `upscale`, `enhance`, `bg-remove`, `outpaint`.
- `image` (string): The JPEG, PNG or WebP to work on, up to 15 MB: a public `https://` link we fetch, a `data:image/…;base64,` URI, or bare base64. With multipart form data, attach the file itself (`-F image=@house.jpg`). Send one of `image` or `job_id`.
- `job_id` (string): A finished job of yours: work on its output without downloading it first.
- `creativity` (integer): `enhance` only: 0 keeps closest to the image, 100 reinvents the most.
- `prompt` (string): `enhance` or `outpaint` only: a direction, in plain words.
- `aspect_ratio` (string): `outpaint` only, and required there: the shape to extend the image to. Values: `1:1`, `3:2`, `4:3`, `5:4`, `16:9`, `21:9`, `2:3`, `3:4`, `4:5`, `9:16`.
- `webhook_url` (string): A public `https://` URL to send this job’s settle event to, signed like every [webhook](https://developers.mnml.ai/docs/webhooks), on top of your account’s endpoints.

## Response

On success (`202`): Started. Poll GET /v2/jobs/{id} for the result. The JSON is `{ "success": true, "data": … }`, and inside `data`:

- `id` (string, required): The job. Read it at [GET /v2/jobs/{id}](https://developers.mnml.ai/docs/jobs).
- `status` (string, required): The job’s status when it was accepted, usually `queued`. Values: `queued`, `processing`, `succeeded`, `failed`, `canceled`.
- `charged_usd` (number, required): What this call charged, in US dollars. A job that fails is refunded.
- `replayed` (boolean, required): True when this is the stored answer to an earlier identical request with the same `Idempotency-Key`: nothing ran or was charged again. See [Idempotency](https://developers.mnml.ai/docs/idempotency).
- `notes` (string[], required): What was accepted but not applied, in plain words: a setting that does not fit the engine, a seed it does not take. Empty when everything applied.

**Response headers (5)**

- `X-Request-Id` (string): This request, for support and the console log.
- `RateLimit-Limit` (integer): Requests this key may make per minute.
- `RateLimit-Remaining` (integer): Requests left in the current minute.
- `RateLimit-Reset` (integer): Seconds until the current minute resets.
- `Idempotent-Replayed` (string): Present, as `true`, when this is the stored answer to an earlier request.

## Status codes

| Status | Meaning |
| --- | --- |
| 202 | Started. Poll GET /v2/jobs/{id} for the result. |
| 401 | The API key is missing, malformed, unknown or revoked. |
| 402 | The balance does not cover this call. |
| 409 | The Idempotency-Key was reused for a different request, or is still in progress. |
| 429 | A limit was reached: requests per minute, or a daily or concurrency limit. |
| Other | Any other error, in the same envelope. |

Every error answers `{ "success": false, "error": { "code", "message" } }`. What each code means, and what to do, is on [Errors](https://developers.mnml.ai/docs/errors).
