# Polish shoot images

> Correct the light and colour of finished images of one of your shoots, keeping everything else. One polished file per image.

**Endpoint:** `POST https://api.refabric.com/v1/tasks/image.polish` · **Task:** `image.polish` · **Scope:** `tasks:run` · **Category:** Image editing

Send finished images of one of your shoots and get each back with its light and colour corrected. Send one image to polish it again; send several and any already polished is skipped and not charged.

## Quick start

```python
import os
import time
import requests

headers = {"Authorization": f"Key {os.environ['REFABRIC_API_KEY']}"}

job = requests.post(
    "https://api.refabric.com/v1/tasks/image.polish",
    headers=headers,
    json={
        "images": [
            "https://files.example.com/image.polish/1.png",
            "https://files.example.com/image.polish/2.png",
        ],
    },
).json()
print(job["job_id"])

while True:
    status = requests.get(job["status_url"], headers=headers).json()
    if status["lifecycle"] == "terminal":
        break
    time.sleep(5)

print(requests.get(job["result_url"], headers=headers).json())
```

```javascript
const headers = {
  Authorization: `Key ${process.env.REFABRIC_API_KEY}`,
  "Content-Type": "application/json",
};

const job = await fetch("https://api.refabric.com/v1/tasks/image.polish", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "images": [
      "https://files.example.com/image.polish/1.png",
      "https://files.example.com/image.polish/2.png"
    ]
  }),
}).then((r) => r.json());
console.log(job.job_id);

let status = job;
while (status.lifecycle !== "terminal") {
  await new Promise((r) => setTimeout(r, 5000));
  status = await fetch(job.status_url, { headers }).then((r) => r.json());
}

console.log(await fetch(job.result_url, { headers }).then((r) => r.json()));
```

```bash
curl -X POST "https://api.refabric.com/v1/tasks/image.polish" \
  -H "Authorization: Key $REFABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait=60" \
  -d '{"images":["https://files.example.com/image.polish/1.png","https://files.example.com/image.polish/2.png"]}'
```

## Input schema

- `images` (array<string>, _required_, at least 1 items, at most 400 items) — 1–400 images of ONE of your shoots, each as one string: an `items[].url` of `GET /v1/files/photoshoot:<id>` (or its `art:` file). Each is polished once, at the shoot's resolution.
  Example: `["https://files.example.com/image.polish/1.png","https://files.example.com/image.polish/2.png"]`

## Required-fields example

```json
{
  "images": [
    "https://files.example.com/image.polish/1.png",
    "https://files.example.com/image.polish/2.png"
  ]
}
```

## Full example

```json
{
  "images": [
    "https://files.example.com/image.polish/1.png",
    "https://files.example.com/image.polish/2.png"
  ]
}
```

## Output schema

- `files` (array<object>, _optional_) — One `image/*` file per polished image. An image already polished in a batch of several is skipped (not charged).
- `summary` (object, _optional_) — How many images were polished or tried, how many were polished, and a warning when some could not be.
  - `requested` (integer, _optional_) — The images polished or tried.
  - `delivered` (integer, _optional_) — The images polished.
  - `warnings` (array<object>, _optional_) — One `output_not_produced` row (`field: "images"`) when some images could not be polished; they are not charged.

## Response example

```json
{
  "job_id": "3123456789abcdef0123456789abcdef",
  "lifecycle": "queued",
  "status_url": "http://v3-api.refabric.com/v1/jobs/3123456789abcdef0123456789abcdef",
  "result_url": "http://v3-api.refabric.com/v1/jobs/3123456789abcdef0123456789abcdef/result",
  "cancel_url": "http://v3-api.refabric.com/v1/jobs/3123456789abcdef0123456789abcdef/cancel"
}
```

## Result example

```json
{
  "job_id": "3123456789abcdef0123456789abcdef",
  "files": [
    {
      "file": "art:7d01aa",
      "url": "https://files.example.com/image.polish/3.png",
      "media_type": "image/png",
      "task": "image.polish",
      "job_id": "3123456789abcdef0123456789abcdef",
      "created_at": "2026-10-01T11:02:10Z"
    },
    {
      "file": "art:7d01ab",
      "url": "https://files.example.com/image.polish/4.png",
      "media_type": "image/png",
      "task": "image.polish",
      "job_id": "3123456789abcdef0123456789abcdef",
      "created_at": "2026-10-01T11:02:14Z"
    }
  ],
  "has_more": false,
  "summary": {
    "requested": 2,
    "delivered": 2
  }
}
```

The images are `data.items[].url` of one `photoshoot:<id>` (or their `art:` files); images from two shoots are refused with `image_not_from_shoot`. Each polished file is saved on the shoot next to the image it corrects.

## Built for

- Even light and colour across a shoot before you publish it
- Touching up one image of a shoot

## What you get

- One image file per image polished.
- A `summary` that counts the images polished and warns when some could not be; those are not charged.

## Specs

- **Input formats:** Images, each one string: a URL, an upload (`file:…`) or a file from an earlier result (`art:…`). Upload types and sizes: `GET /v1/meta` `limits.upload`. `images` takes only files from `photoshoot.create`, `ghost_photoshoot.create`, `mannequin_photoshoot.create`.
- **Input count:** `images`: 1 to 400
- **Output format:** Files: each one line with its `url` and its `media_type`, in the job's result.
- **Outputs per job:** At most one file per image you send.

## Errors

- `field_not_accepted`
- `invalid_request`
- `images_required`
- `too_many_images`
- `image_not_from_shoot`
- `request_refused`
- `insufficient_credits`
- `permission_denied`
- `processing_failed`

## Related

- `photoshoot.create` — It runs before: its result is this input.
- `ghost_photoshoot.create` — It runs before: its result is this input.
- `mannequin_photoshoot.create` — It runs before: its result is this input.

## Good to know

- `images` holds at least 1 items.
- `images` holds at most 400 items.

## For agents and code generation

- https://api.refabric.com/v1/tasks/image.polish/llms.txt
- https://api.refabric.com/v1/tasks/image.polish/openapi.json
- GET https://api.refabric.com/v1/tasks/image.polish
