# Pixelcut Product Photo API

> Công cụ ghép ảnh sản phẩm: tách sản phẩm và đặt lên canvas mới với nền, lề và bóng

Xử lý ảnh sản phẩm thành hình ảnh kiểu danh mục. Bạn có thể đặt canvas bằng các thiết lập sẵn `image_size` hoặc kích thước tùy chỉnh, chọn `background` dạng đặc, trong suốt hoặc hình ảnh, và điều chỉnh `margin`. Có thể thêm `shadow` tạo sinh hoặc đổ bóng, cùng lớp phủ `watermark` tùy chọn. Đầu ra là png hoặc jpeg; jpeg không thể dùng với nền trong suốt.

- Model id: `pixelcut/product-photo`
- Made by: Pixelcut
- Category: Image Editing
- Output: image
- Price: $0.024 / image (cheapest run $0.024 (24 API credits))
- Run: `POST https://api.doitong.com/v1/run/pixelcut/product-photo`
- Quote: `POST https://api.doitong.com/v1/quote/pixelcut/product-photo`
- Docs page: https://doitong.com/vi/developers/models/pixelcut/product-photo

## Pricing

Price: **$0.024 / image**. Billed per generated image.

The full example input below costs $0.024 = 24 API credits (1 image × 24 API credits).

Prices are the upstream price in USD, paid from the API balance in API credits (1000 API credits = 1 USD). `POST https://api.doitong.com/v1/quote/pixelcut/product-photo` with the same JSON body returns the exact price for that input; the quote is exactly what a run charges. Invalid input is never charged and failed or canceled requests are refunded automatically.

## Input parameters

Send either the canonical name or the native field name (not both). Canonical names are the same across models.

| Parameter | Canonical name | Type | Required | Default | Allowed values / range | Description |
|---|---|---|---|---|---|---|
| `image_url` | `image` | string (image URL) | yes |  |  | URL hình ảnh sản phẩm để xử lý. |
| `image_size` |  | object {width, height} \| enum (string) \| null | no | `square_hd` | `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9` | Kích thước canvas đầu ra, được chỉ định dưới dạng tùy chỉnh {width, height} hoặc một giá trị đặt trước: square_hd, square, portrait_4_3, portrait_16_9, landscape_4_3, landscape_16_9. Mặc định là square_hd (1024x1024). |
| `background` |  | object {mode, color, image_url, image_fit} | no |  |  | Nền cho đầu ra: hình ảnh, trong suốt hoặc màu đồng nhất, mặc định là màu trắng. |
| `background.mode` |  | enum (string) | no | `Color` | `Transparent`, `Color`, `Image` | Chế độ nền: 'Color' dùng `color`, mặc định là màu trắng; 'Transparent' tạo nền trong suốt và luôn dùng PNG; 'Image' ghép kết quả lên `image_url`. |
| `background.color` |  | object {r, g, b} | no | `{"b":255,"g":255,"r":255}` |  | Màu nền đồng nhất cho chế độ 'Color', mặc định là màu trắng, được chỉ định bằng các thành phần R/G/B trong khoảng từ 0 đến 255. |
| `background.color.r` |  | integer | yes |  | 0 – 255 |  |
| `background.color.g` |  | integer | yes |  | 0 – 255 |  |
| `background.color.b` |  | integer | yes |  | 0 – 255 |  |
| `background.image_url` |  | string (image URL) \| null | no |  |  | URL của hình ảnh nền; bắt buộc ở chế độ 'Image'. |
| `background.image_fit` |  | enum (string) | no | `Cover` | `Cover`, `Contain`, `Stretch` | Chọn cách căn hình ảnh nền vào canvas. 'Contain' giữ nguyên hình ảnh vừa khít với phần viền đen trên `color`, 'Stretch' làm biến dạng để vừa khít; 'Cover' lấp đầy canvas bằng cách cắt ảnh. |
| `margin` |  | object {all, left, right, top, bottom} | no |  |  | Khoảng cách giữa sản phẩm và các cạnh canvas. Dùng `all` để đặt mọi lề, với tùy chọn ghi đè cho từng cạnh; mặc định là 20% mỗi cạnh. |
| `margin.all` |  | string | no | `20%` |  | Lề đồng nhất ở mọi cạnh, được chỉ định theo '%' của kích thước canvas, từ 0 đến 49%, hoặc bằng 'px' với tối thiểu 0px. |
| `margin.left` |  | string \| null | no |  |  | Lề trái thay thế `all` ở cạnh đó. Chấp nhận '%' từ 0 đến 49% hoặc 'px' từ 0px trở lên. |
| `margin.right` |  | string \| null | no |  |  | Lề phải thay thế `all` ở cạnh đó. Chấp nhận '%' từ 0 đến 49% hoặc 'px' từ 0px trở lên. |
| `margin.top` |  | string \| null | no |  |  | Lề trên thay thế `all` ở cạnh đó. Chấp nhận '%' từ 0 đến 49% hoặc 'px' từ 0px trở lên. |
| `margin.bottom` |  | string \| null | no |  |  | Lề dưới thay thế `all` ở cạnh đó. Chấp nhận '%' từ 0 đến 49% hoặc 'px' từ 0px trở lên. |
| `shadow` |  | object {type, generative, drop} | no |  |  | Cấu hình bóng: chọn 'Generative' hoặc 'Drop' và định cấu hình các thiết lập. Để trống để không áp dụng bóng. |
| `shadow.type` |  | enum (string) \| null | no |  | `Generative`, `Drop` | Kiểu bóng tùy chọn, không có bóng khi để trống. Chọn 'Generative' để tổng hợp bằng AI hoặc 'Drop' cho bóng đổ xác định. |
| `shadow.generative` |  | object {opacity, light_source} | no |  |  | Thiết lập cho bóng do AI tạo, được áp dụng khi loại là 'Generative'. |
| `shadow.generative.opacity` |  | number | no | `0.2` | 0 – 1 | Độ mờ của bóng được ghép hoàn chỉnh, từ 0 đến 1. |
| `shadow.generative.light_source` |  | object {size, position} \| null | no |  |  | Nguồn sáng ảo cụ thể để tổng hợp bóng, thay thế ước tính tự động về hướng sáng từ hình ảnh khi được cung cấp. |
| `shadow.drop` |  | object {color, horizontal, vertical, blur, opacity} | no |  |  | Thiết lập cho bóng đổ, được áp dụng khi loại là 'Drop'. |
| `shadow.drop.color` |  | object {r, g, b} | no | `{"b":0,"g":0,"r":0}` |  | Màu RGB của bóng; mặc định là màu đen. |
| `shadow.drop.horizontal` |  | number | no | `50` | -100 – 100 | Độ dịch chuyển bóng theo chiều ngang, trong đó thiết lập tối đa 100 tương ứng với 10% chiều rộng canvas. Giá trị từ -100 đến 100; giá trị âm dịch sang trái và giá trị dương dịch sang phải. |
| `shadow.drop.vertical` |  | number | no | `8` | -100 – 100 | Độ dịch chuyển bóng theo chiều dọc, trong đó thiết lập tối đa 100 tương ứng với 10% chiều cao canvas. Giá trị từ -100 đến 100; giá trị âm dịch lên trên và giá trị dương dịch xuống dưới. |
| `shadow.drop.blur` |  | number | no | `24` | 0 – 100 | Thiết lập độ mờ bóng, trong đó độ mềm tối đa ở 100 tương ứng với bán kính bằng 5% kích thước canvas ngắn hơn. Phạm vi bắt đầu từ 0, giữ cho các cạnh cứng. |
| `shadow.drop.opacity` |  | number | no | `0.25` | 0 – 1 | Độ mờ của bóng, từ 0 đến 1. |
| `watermark` |  | object {image_url, remove_background, position, scale, opacity, margin} \| null | no |  |  | Lớp phủ logo hoặc hình mờ được bật khi cung cấp hình ảnh; bỏ qua hình ảnh sẽ giữ đầu ra không có hình mờ như mặc định. |
| `watermark.image_url` |  | string (image URL) \| null | no |  |  | URL của hình ảnh logo hoặc hình mờ. Giá trị trống giữ đầu ra không có hình mờ. |
| `watermark.remove_background` |  | boolean | no | `false` |  | Có loại bỏ nền của hình mờ bằng tính năng loại bỏ nền để lớp phủ không bao gồm nền đó hay không. |
| `watermark.position` |  | enum (string) | no | `bottom_right` | `top_left`, `top_right`, `bottom_left`, `bottom_right`, `center` | Vị trí của hình mờ. |
| `watermark.scale` |  | number | no | `0.1` | 0.01 – 1 | Chiều rộng của hình mờ, biểu thị theo tỷ lệ chiều rộng canvas. |
| `watermark.opacity` |  | number | no | `1` | 0 – 1 | Độ mờ của hình mờ, từ 0 đến 1. |
| `watermark.margin` |  | string | no | `3%` |  | Khoảng cách vào phía trong tính từ cạnh canvas, biểu thị theo '%' của canvas (0–49%) hoặc bằng 'px'. |
| `output_format` |  | enum (string) \| null | no |  | `png`, `jpeg` | Mã hóa hình ảnh đầu ra, chọn PNG hoặc JPEG; JPEG không khả dụng cho nền trong suốt. Bỏ qua lựa chọn sẽ giữ nguyên định dạng của đầu vào. |

File parameters (`image`) take a public `https://` URL, a `data:` URI up to 10 MB, or the `file_url` of an upload from `POST /files`.

## Example input

Required parameters only:

```json
{
  "image": "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
}
```

A fuller example:

```json
{
  "image_url": "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
}
```

## Run it

Set `DOITONG_API_KEY` to a key from https://doitong.com/developers/dashboard#keys. `?wait=20` returns the finished request in the same call when it is ready within 20 seconds; otherwise poll `GET /requests/{id}` (it also accepts `?wait=`), or pass `webhook_url`.

### curl

```bash
# Run the model; wait up to 20 s for the finished result in the same call
curl -X POST "https://api.doitong.com/v1/run/pixelcut/product-photo?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
  }'

# Still "queued" or "running"? Poll with the id from the response:
curl "https://api.doitong.com/v1/requests/REQUEST_ID?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
```

### JavaScript

```javascript
const API = "https://api.doitong.com/v1";
const headers = {
  "Authorization": "Bearer " + process.env.DOITONG_API_KEY,
  "Content-Type": "application/json",
};

// Run the model; wait up to 20 s for the finished result in the same call
let res = await fetch(API + "/run/pixelcut/product-photo?wait=20", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "image_url": "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
  }),
});
let request = await res.json();
if (!res.ok) throw new Error(request.error.code + ": " + request.error.message);

// Not finished yet: long-poll until it is
while (request.status === "queued" || request.status === "running") {
  res = await fetch(API + "/requests/" + request.id + "?wait=20", { headers });
  request = await res.json();
}
if (request.status !== "succeeded") throw new Error(JSON.stringify(request.error));
console.log(request.outputs.map((o) => o.url), request.cost.credits + " API credits ($" + request.cost.usd + ")");
```

### Python

```python
import os
import requests

API = "https://api.doitong.com/v1"
headers = {"Authorization": "Bearer " + os.environ["DOITONG_API_KEY"]}

payload = {
    "image_url": "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg",
}

# Run the model; wait up to 20 s for the finished result in the same call
r = requests.post(API + "/run/pixelcut/product-photo", params={"wait": 20}, json=payload, headers=headers)
request = r.json()
if not r.ok:
    raise RuntimeError(request["error"]["code"] + ": " + request["error"]["message"])

# Not finished yet: long-poll until it is
while request["status"] in ("queued", "running"):
    request = requests.get(API + "/requests/" + request["id"], params={"wait": 20}, headers=headers).json()
if request["status"] != "succeeded":
    raise RuntimeError(request["error"])
print([o["url"] for o in request["outputs"]], request["cost"]["credits"], "API credits", "$" + request["cost"]["usd"])
```

### MCP

The MCP server at `https://api.doitong.com/v1/mcp` exposes the tools `search_models`, `get_model`, `quote`, `run`, `get_request`, `cancel_request`, `list_requests`, `create_upload` and `get_account`. A `run` call for this model:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "run",
    "arguments": {
      "model_id": "pixelcut/product-photo",
      "input": {
        "image_url": "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
      },
      "wait_seconds": 20
    }
  }
}
```

## Response

Every call returns a request object. `status` is one of `queued`, `running`, `succeeded`, `failed`, `canceled`. `outputs` lists the generated files with URLs on our storage (kept forever, or 7 days with `?storage=temporary`; `storage` says which); `output` is the model's own result object with the same URLs.

```json
{
  "id": "req_8k2m4q7x1z9c3v5b6n0p2r4t",
  "object": "request",
  "model": "pixelcut/product-photo",
  "status": "succeeded",
  "created_at": "2026-10-20T12:00:00Z",
  "started_at": "2026-10-20T12:00:02Z",
  "completed_at": "2026-10-20T12:00:09Z",
  "queue_position": null,
  "cost": {
    "credits": 24,
    "usd": "0.024",
    "charged": 24,
    "refunded": 0
  },
  "input": {
    "image_url": "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
  },
  "output": {
    "image": {
      "url": "https://content.doitong.com/dev-api/2026/10/20/req_8k2m4q7x1z9c3v5b6n0p2r4t/0-output.jpeg",
      "content_type": "image/jpeg",
      "file_name": "0-output.jpeg",
      "file_size": 1843200,
      "width": 1024,
      "height": 768
    }
  },
  "outputs": [
    {
      "type": "image",
      "url": "https://content.doitong.com/dev-api/2026/10/20/req_8k2m4q7x1z9c3v5b6n0p2r4t/0-output.jpeg",
      "content_type": "image/jpeg",
      "file_size": 1843200,
      "width": 1024,
      "height": 768,
      "stored": true
    }
  ],
  "error": null,
  "metrics": {
    "inference_seconds": 6.8
  },
  "urls": {
    "self": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t",
    "cancel": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel"
  }
}
```

### Output fields (`output`)

| Field | Type | Description |
|---|---|---|
| `image` | object {url, content_type, file_name, file_size, width, height} \| null | Ảnh sản phẩm được chuẩn bị để dùng trong danh mục. |

## Related models

- [Pixelcut Looping Video](https://doitong.com/developers/models/pixelcut/looping-video.md) (`pixelcut/looping-video`): from $0.08 / second
- [Pixelcut Background Remover](https://doitong.com/developers/models/pixelcut/background-removal.md) (`pixelcut/background-removal`): $0.016 / image
- [Pixelcut Video Background Removal](https://doitong.com/developers/models/pixelcut/video-background-removal.md) (`pixelcut/video-background-removal`): $0.022 / 30 frames of input video
- [FLUX.1 Kontext \[pro\]](https://doitong.com/developers/models/flux-pro/kontext.md) (`flux-pro/kontext`): $0.04 / image
- [GPT Image 2.5 Edit](https://doitong.com/developers/models/openai/gpt-image-2.5/flare/edit.md) (`openai/gpt-image-2.5/flare/edit`): from $0.12 / image
- [Nano Banana 2 Edit](https://doitong.com/developers/models/nano-banana-2/edit.md) (`nano-banana-2/edit`): from $0.06 / image
- [Nano Banana Pro Edit](https://doitong.com/developers/models/nano-banana-pro/edit.md) (`nano-banana-pro/edit`): from $0.15 / image
- [Qwen Image 3 Edit](https://doitong.com/developers/models/alibaba/qwen-image-3/edit.md) (`alibaba/qwen-image-3/edit`): from $0.04 / image

## Links

- HTML page: https://doitong.com/developers/models/pixelcut/product-photo
- All models and guides for AI agents: https://doitong.com/developers/llms.txt
- OpenAPI 3.1 with this model's typed request body: https://doitong.com/developers/openapi.json?model=pixelcut/product-photo
- Errors: https://doitong.com/developers/docs/errors
- Model details as JSON: https://api.doitong.com/v1/models/pixelcut/product-photo
