# Rotate an image to its other views

> Turn the subject of an image around: its back, left and right views, keeping its medium and style. Delivered as up to three image files, in that order.

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

Send an image and get its subject from the other sides: the back, the left and the right. The medium and the style of your image are kept. A view that cannot be made is left out 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.rotate_views",
    headers=headers,
    json={
        "image": "art:5c8f01",
    },
).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.rotate_views", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "image": "art:5c8f01"
  }),
}).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.rotate_views" \
  -H "Authorization: Key $REFABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait=60" \
  -d '{"image":"art:5c8f01"}'
```

## Input schema

- `image` (string, _required_, pattern: ^(https://|art:|file:).+$) — The image to turn, as one string: a URL, a file from an earlier result (`art:…` or its url) or an upload (`file:…`). Its subject, medium and style are kept. If it is one of your files placed on a design, the views are filed there too.
  Example: `art:5c8f01`

## Required-fields example

```json
{
  "image": "art:5c8f01"
}
```

## Full example

```json
{
  "image": "art:5c8f01"
}
```

## Output schema

- `files` (array<object>, _optional_, at most 3 items) — Up to three `image/*` files, always in this order: the back (turned 180°), the left (+90°) and the right (−90°) of the image's subject. A view that could not be made is left out and named in `summary.warnings`; you are charged only for the views delivered.
- `summary` (object, _optional_) — How many of the three views were made, and which are missing.
  - `requested` (integer, _optional_) — Always 3: back, left, right.
  - `delivered` (integer, _optional_) — How many views were made.
  - `warnings` (array<object>, _optional_) — One `{code: "output_not_produced", field, message}` row per missing view, `field` naming it: `"back"`, `"left"` or `"right"`.

## Response example

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

## Result example

```json
{
  "job_id": "7a1c2e3f00004000800000000000001b",
  "files": [
    {
      "file": "art:5c8f02",
      "url": "https://files.example.com/image.rotate_views/1.png",
      "media_type": "image/png",
      "task": "image.rotate_views",
      "job_id": "7a1c2e3f00004000800000000000001b",
      "created_at": "2026-10-01T09:20:31Z"
    },
    {
      "file": "art:5c8f04",
      "url": "https://files.example.com/image.rotate_views/2.png",
      "media_type": "image/png",
      "task": "image.rotate_views",
      "job_id": "7a1c2e3f00004000800000000000001b",
      "created_at": "2026-10-01T09:20:33Z"
    }
  ],
  "has_more": false,
  "summary": {
    "requested": 3,
    "delivered": 2,
    "warnings": [
      {
        "code": "output_not_produced",
        "field": "left",
        "message": "The left view could not be made."
      }
    ]
  }
}
```

The files are always back, left, right; here the left view could not be made, so the files are the back and the right, and the warning names the missing view.

## Built for

- Back and side views for a tech pack
- A turnaround of a design
- The sides of a garment you only have from the front

## What you get

- Up to three images: the back, the left and the right view.
- A `summary` that counts the views made and names each one that is missing.

## 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`.
- **Input count:** `image`: one
- **Output format:** Files: each one line with its `url` and its `media_type`, in the job's result.
- **Outputs per job:** Up to three image files, one per view made.

## Choosing a task

- Use this when you want the same subject seen from behind and from the sides. Use `image.repose` when you want a person in the same clothes in new poses.

## Errors

- `field_not_accepted`
- `invalid_request`
- `not_found`
- `permission_denied`
- `insufficient_credits`
- `processing_failed`

## Related

- `image.generate` — It runs before: its result is this input.
- `image.to_sketch` — It does a neighbouring job.

## For agents and code generation

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