# PATINA · Material API

> タイル可能な画像とPBRマップを出力するテキストからテクスチャへの生成モデル。任意でimg2imgとインペイントに対応

プロンプトからタイル可能なテクスチャを作成し、PBRマップ（basecolor、normal、roughness、metalness、height）を推定します。`tiling_mode`では両方向、水平、垂直のタイル化を選択でき、`upscale_factor`は0、2、4でマップを拡大します。`image_url`を渡すと画像から画像への変換、`mask_url`を追加するとインペイントが有効になります。リクエストあたり最大4枚です。

- Model id: `patina/material`
- Made by: Open model
- Category: Text to Image
- Output: image
- Price per run: from $0.08 / run (cheapest run $0.08 (80 API credits))
- Run: `POST https://api.doitong.com/v1/run/patina/material`
- Quote: `POST https://api.doitong.com/v1/quote/patina/material`
- Docs page: https://doitong.com/ja/developers/models/patina/material

## Pricing

Price: **from $0.08 / run** (the lowest tier; the quote prices your exact input). Price per run: the input files are measured before the run (length, resolution, frame rate). The quote measures the same files and is exactly what the run charges.

The full example input below costs $0.08 = 80 API credits (1 run × $0.08).

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/patina/material` 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 |
|---|---|---|---|---|---|---|
| `prompt` |  | string | yes |  |  | 作成するマテリアルまたはテクスチャのテキスト説明。 |
| `image_size` |  | object {width, height} \| enum (string) | no | `square_hd` | `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9` | 生成されるテクスチャのピクセル寸法。 |
| `num_inference_steps` |  | integer | no | `8` | 1 – 8 | テクスチャ生成に使用するノイズ除去ステップ数。 |
| `seed` |  | integer \| null | no |  |  | 生成を再現可能にするランダムシード。 |
| `num_images` | `num_outputs` | integer | no | `1` | 1 – 4 | 作成するテクスチャ画像の数。 |
| `enable_prompt_expansion` |  | boolean | no | `true` |  | 詳細を追加するLLMベースのプロンプト拡張を有効にします。 |
| `enable_safety_checker` |  | boolean | no | `true` |  | 生成画像の安全性チェックを有効にします。 |
| `tiling_mode` |  | enum (string) | no | `both` | `both`, `horizontal`, `vertical` | タイリングの方向。全方向のタイリングには'both'、または'horizontal'、'vertical'を指定します。 |
| `tile_size` |  | integer | no | `128` | 32 – 256 | 潜在空間のタイルサイズ。64は512px、128は1024pxを表します。タイリングする各軸では、生成画像の寸法が自動上限になります。 |
| `tile_stride` |  | integer | no | `64` | 16 – 128 | 潜在空間タイル間のストライドを設定します。自動上限により、有効なタイルサイズの半分を超えないように制限されます。 |
| `image_url` | `image` | string (image URL) \| null | no |  |  | ソース画像URL。mask_urlを伴う場合はインペインティングに使用し、それ以外では画像間処理に使用します。 |
| `mask_url` | `mask` | string (image URL) \| null | no |  |  | 必須のimage_urlとともに指定するインペインティングマスクURL。黒い領域は変更せず、白い領域を再生成します。 |
| `strength` |  | number | no | `0.6` | ≤ 1, > 0 | image_urlから提供された画像にのみ適用する変換強度。それ以外では使用されません。 |
| `maps` |  | array of enum (string) | no | `["basecolor","normal","roughness","metalness","height"]` |  | 予測対象として選択するPBRマップ。デフォルトでは5種類すべてが選択されます。何も選択しない場合、PBR推定全体をスキップします。 |
| `upscale_factor` |  | enum (integer) | no | `0` | `0`, `2`, `4` | 予測されたPBRマップに適用するSeedVRシームレスアップスケール倍率。ベーステクスチャは元の解像度のままです。2で2倍、4で4倍の解像度、0でアップスケールを無効にします。 |
| `output_format` |  | enum (string) | no | `png` | `jpeg`, `png`, `webp` | 出力テクスチャおよびPBRマップの画像ファイル形式。 |

File parameters (`image`, `mask`) 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
{
  "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
}
```

A fuller example:

```json
{
  "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
}
```

## 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/patina/material?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
  }'

# 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/patina/material?wait=20", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
  }),
});
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 = {
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field",
}

# Run the model; wait up to 20 s for the finished result in the same call
r = requests.post(API + "/run/patina/material", 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": "patina/material",
      "input": {
        "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
      },
      "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": "patina/material",
  "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": 80,
    "usd": "0.08",
    "charged": 80,
    "refunded": 0
  },
  "input": {
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
  },
  "output": {
    "images": [
      {
        "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
      }
    ],
    "seed": 42,
    "prompt": "string",
    "timings": {}
  },
  "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 |
|---|---|---|
| `images` | array of any | 出力画像には、z-imageで生成されたタイル可能なテクスチャとともに、PATINAが予測したPBRマテリアルマップが含まれます。 |
| `seed` | integer | テクスチャ生成時に適用するシード。 |
| `prompt` | string | 適用された拡張を含むテクスチャ生成プロンプト。 |
| `timings` | object | 全処理を対象とした秒単位のタイミング内訳。 |

## Related models

- [PATINA](https://doitong.com/developers/models/patina.md) (`patina`): from $0.0225 / run of input image
- [PATINA · Material · Extract](https://doitong.com/developers/models/patina/material/extract.md) (`patina/material/extract`): from $0.17 / run
- [FLUX.1 \[dev\]](https://doitong.com/developers/models/flux/dev.md) (`flux/dev`): $0.025 / megapixel
- [FLUX.1 \[schnell\]](https://doitong.com/developers/models/flux/schnell.md) (`flux/schnell`): $0.003 / megapixel
- [FLUX.2 \[dev\]](https://doitong.com/developers/models/flux-2.md) (`flux-2`): $0.012 / megapixel
- [FLUX.2 \[pro\]](https://doitong.com/developers/models/flux-2-pro.md) (`flux-2-pro`): $0.015 / megapixel of output image
- [GPT Image 2.5 Text to Image](https://doitong.com/developers/models/openai/gpt-image-2.5/flare/text-to-image.md) (`openai/gpt-image-2.5/flare/text-to-image`): from $0.008 / image
- [Ideogram V4.5](https://doitong.com/developers/models/ideogram/v4.5.md) (`ideogram/v4.5`): from $0.03 / image

## Links

- HTML page: https://doitong.com/developers/models/patina/material
- 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=patina/material
- Errors: https://doitong.com/developers/docs/errors
- Model details as JSON: https://api.doitong.com/v1/models/patina/material
