# POST /api/items

商品作成

新しい商品を作成します。

この API では、商品名や価格などの基本的な情報を設定できます。
種類や画像、カテゴリなどは、作成後にそれぞれのエンドポイントで追加することができます。

商品は非公開で作成されます。
公開状態は `PUT /api/items/{id}/visibility` で変更することができます。

## 要求スコープ

- `items.create`
- `items.read`

## リクエストボディ

`application/json`

`type` の値により分岐します。

- ItemCreateInputNormal の場合
  - `type` "normal"（必須）: 商品種別。normal=デジタルコンテンツ・テイクアウト・定期便・抽選販売のいずれにも該当しない通常商品。
  - `name` string（必須 / 1 文字以上 / 255 文字以下）: 商品名（1〜255 文字）。絵文字などの 4 バイト文字は使用できません。
  - `detail` string | null（任意 / 65535 文字以下）: 商品説明文（最大 65535 文字）。絵文字などの 4 バイト文字は使用できません。null を指定すると値をクリアします。
  - `identifier` string | null（任意 / 50 文字以下 / pattern: ^[a-zA-Z0-9_-]+$）: 商品コード（最大 50 文字）。半角英数字と「_」「-」のみ指定できます。null を指定すると値をクリアします。
  - `price` integer（必須 / ≥ 50 / ≤ 100000000）: 販売価格（税込、円、50〜100000000 円）。ショップの設定により上限が異なります。割引は別の sale エンドポイントで設定します。
  - `item_tax_type` ItemTaxType（必須）: 税区分。standard=標準税率、reduced=軽減税率。
  - `quantity_limit` integer | null（任意 / ≥ 1 / ≤ 100）: 同時購入数の上限（1〜100）。null を指定すると値をクリアします。
- ItemCreateInputTakeout の場合
  - `type` "takeout"（必須）: 商品種別。takeout=テイクアウト。
  - `name` string（必須 / 1 文字以上 / 255 文字以下）: 商品名（1〜255 文字）。絵文字などの 4 バイト文字は使用できません。
  - `detail` string | null（任意 / 65535 文字以下）: 商品説明文（最大 65535 文字）。絵文字などの 4 バイト文字は使用できません。null を指定すると値をクリアします。
  - `identifier` string | null（任意 / 50 文字以下 / pattern: ^[a-zA-Z0-9_-]+$）: 商品コード（最大 50 文字）。半角英数字と「_」「-」のみ指定できます。null を指定すると値をクリアします。
  - `price` integer（必須 / ≥ 50 / ≤ 100000000）: 販売価格（税込、円、50〜100000000 円）。ショップの設定により上限が異なります。割引は別の sale エンドポイントで設定します。
  - `item_tax_type` ItemTaxType（必須）: 税区分。standard=標準税率、reduced=軽減税率。
  - `quantity_limit` integer | null（任意 / ≥ 1 / ≤ 100）: 同時購入数の上限（1〜100）。null を指定すると値をクリアします。
- ItemCreateInputSubscription の場合
  - `type` "subscription"（必須）: 商品種別。subscription=定期便。
  - `name` string（必須 / 1 文字以上 / 255 文字以下）: 商品名（1〜255 文字）。絵文字などの 4 バイト文字は使用できません。
  - `detail` string | null（任意 / 65535 文字以下）: 商品説明文（最大 65535 文字）。絵文字などの 4 バイト文字は使用できません。null を指定すると値をクリアします。
  - `identifier` string | null（任意 / 50 文字以下 / pattern: ^[a-zA-Z0-9_-]+$）: 商品コード（最大 50 文字）。半角英数字と「_」「-」のみ指定できます。null を指定すると値をクリアします。
  - `price` integer（必須 / ≥ 50 / ≤ 100000000）: 販売価格（税込、円、50〜100000000 円）。ショップの設定により上限が異なります。割引は別の sale エンドポイントで設定します。
  - `item_tax_type` ItemTaxType（必須）: 税区分。standard=標準税率、reduced=軽減税率。
  - `quantity_limit` integer | null（任意 / ≥ 1 / ≤ 100）: 同時購入数の上限（1〜100）。null を指定すると値をクリアします。
  - `subscription` ItemSubscriptionInput（必須）: 定期便のリピート時の価格・リピート回数・課金周期。初回価格（initial_price）は商品価格とリピート時の価格から決まるため、指定できません。
    - `repeat_price` integer（任意 / ≥ 50 / ≤ 100000000）: 継続サイクルの販売価格（税込、円、50〜100000000 円）。ショップの設定により上限が異なります。省略時は商品本体価格と同額になり、初回・継続の価格が同じになります。
    - `repeat_times` ItemSubscriptionRepeatTimes（必須）: リピート回数。repeat_3_times / repeat_6_times / repeat_12_times は指定回数で終了し、unlimited は停止されるまで継続します。
    - `cycle_plan` ItemSubscriptionCyclePlan（必須）: 課金周期。weekly=毎週、every_2_weeks=隔週、monthly=毎月、every_45_days=45日ごと、every_2_months=隔月、every_3_months=3ヶ月ごと。
- ItemCreateInputLottery の場合
  - `type` "lottery"（必須）: 商品種別。lottery=抽選販売。
  - `name` string（必須 / 1 文字以上 / 255 文字以下）: 商品名（1〜255 文字）。絵文字などの 4 バイト文字は使用できません。
  - `detail` string | null（任意 / 65535 文字以下）: 商品説明文（最大 65535 文字）。絵文字などの 4 バイト文字は使用できません。null を指定すると値をクリアします。
  - `identifier` string | null（任意 / 50 文字以下 / pattern: ^[a-zA-Z0-9_-]+$）: 商品コード（最大 50 文字）。半角英数字と「_」「-」のみ指定できます。null を指定すると値をクリアします。
  - `price` integer（必須 / ≥ 50 / ≤ 100000000）: 販売価格（税込、円、50〜100000000 円）。ショップの設定により上限が異なります。割引は別の sale エンドポイントで設定します。
  - `item_tax_type` ItemTaxType（必須）: 税区分。standard=標準税率、reduced=軽減税率。
  - `quantity_limit` integer | null（任意 / ≥ 1 / ≤ 100）: 同時購入数の上限（1〜100）。null を指定すると値をクリアします。
  - `lottery` ItemLotteryInput（必須）
    - `application_start_at` string (date-time)（必須）: 応募開始日時（ISO 8601・UTC）
    - `application_end_at` string (date-time)（必須）: 応募終了日時（ISO 8601・UTC）
    - `scheduled_announce_at` string (date-time)（必須）: 当落通知予定日時（ISO 8601・UTC）

## レスポンスボディ（200）

`application/json`

- `item_id` integer（必須 / ≥ 0）: 作成・更新された商品の ID

## リクエスト例

```sh
curl -X POST "https://apiv2.thebase.com/api/items" \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{
  "type": "normal",
  "name": "string",
  "detail": "string",
  "identifier": "string",
  "price": 50,
  "item_tax_type": "standard",
  "quantity_limit": 1
}'
```

## レスポンス

| Status | Description |
| --- | --- |
| `200` | 作成成功。作成された商品の ID を返します。 |

## エラー

エラーは `application/problem+json` の Problem 形式で返します。認証・スコープ・予期しない内部エラーなど、すべてのエンドポイントに共通のエラーと構造・判別方法は [エラーレスポンス](/docs/errors.md) を参照してください。

このエンドポイントが返すその他のエラーは次のとおりです。

| Status | Type | Description |
| --- | --- | --- |
| `400` | `/errors/request/malformed-body` | リクエストボディをこのエンドポイントが要求する形式として解釈できない場合に返します。 |
| `400` | `/errors/items/invalid-body` | リクエストボディがエンドポイントのスキーマを満たさない場合に返します。 |
| `413` | `/errors/request/body-too-large` | JSON リクエストボディが 1 MiB の上限を超える場合に返します。 |
| `415` | `/errors/request/unsupported-media-type` | JSON 形式のリクエストボディを要求するエンドポイントに、対応していない Content-Type が指定された、または Content-Type が指定されていない場合に返します。 |
| `422` | `/errors/items/write-rejected` | 商品の作成・編集・削除を業務ルールにより実行できない場合に返します (型整合性違反、種別不可変、ドメイン制約違反など)。細分化された Problem type に対応しない理由のときに返します。 |
| `502` | `/errors/internal/bad-gateway` | BASE API が処理を完了するために必要な内部処理で不整合が発生した場合に返します。 |
| `504` | `/errors/internal/gateway-timeout` | BASE API が処理を完了するために必要な内部処理が制限時間内に完了しなかった場合に返します。 |

