
# 招待の一括作成

`POST /v1/invitations:batch` · 権限 `invitations:write`

1 〜 100 件の招待（`items`）を作成します。各項目は `POST /v1/invitations` のルールに従い、それぞれ個別に書き込まれます。ある項目が失敗しても、他の項目は中断されません。レスポンスは `200 OK` で、`items` はリクエストの順序を保持します。項目の `status` は `201`（新規の招待）、`200`（保留中の招待を再送）、またはエラーの HTTP ステータスのいずれかです。失敗した項目には `code`、`status`、`/items/<i>/…` 形式のフィールドポインタを含む `error` が含まれます。`link_only` の項目の `accept_url` は、このレスポンスでのみ返されます（`Cache-Control: no-store`）。`Idempotency-Key` を指定して再生されたレスポンスにはリンクが含まれず、`secret_redacted: true` が返されます。`organization_id` を指定しない項目は、環境の招待になります。`email` の項目はメールで送信されます。デプロイ環境で招待メールが設定されていない場合は、`501 not_implemented` の項目エラーになります。この環境に存在しない `application_id` は、`404 not_found` の項目エラーになります。作成された各招待は `invitation.created` として監査ログに記録されます。

## リクエスト

| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| `items` | object[] | はい | 1 〜 100 件の招待。各要素は `POST /v1/invitations` のフィールドを持ちます。 |
| `Idempotency-Key` | header | いいえ | 再試行時に、リンクを含まない保存済みの結果を返します。 |

## レスポンス

`200 OK`。項目ごとに 1 件の結果が返されます。

```json
{
  "items": [
    {
      "status": 201,
      "invitation": {
        "id": "inv_01j9xt9v3w4y8z0a2b4c6d8e0g",
        "organization_id": "org_01j9xk3m7q8r2s4t6v8w0y2z4a",
        "email": "ada@example.com",
        "role_ids": [
          "rol_01j9xr7s1t2w6x8y0z2a4b6c8e"
        ],
        "application_id": null,
        "delivery": "link_only",
        "delivery_status": "not_sent",
        "status": "pending",
        "send_count": 1,
        "last_sent_at": "2026-10-12T09:31:00.123456Z",
        "expires_at": "2026-10-19T09:31:00.123456Z",
        "accepted_user_id": null,
        "accepted_at": null,
        "revoked_at": null,
        "created_at": "2026-10-12T09:31:00.123456Z",
        "updated_at": "2026-10-12T09:31:00.123456Z",
        "version": 1,
        "accept_url": "https://acme.eu.keenauth.app/u/login?invitation=<token>"
      }
    },
    {
      "status": 422,
      "error": {
        "code": "validation_failed",
        "status": 422,
        "errors": [
          {
            "pointer": "/items/1/email",
            "code": "invalid_value"
          }
        ]
      }
    }
  ]
}
```

## エラー

| HTTP | code | 発生条件 |
|---|---|---|
| 422 | `validation_failed` | `items` が欠けている、空である、または 100 件を超えています。 |
| 401 | `unauthenticated` | 認証情報が指定されていない、無効、または取り消されています。 |
| 403 | `insufficient_permissions` | 認証情報に必要な権限がありません。特権（`is_privileged`）ロールを持つ項目は、認証情報に `roles:write` がない場合、この項目エラーで失敗します。 |
| 429 | `rate_limited` | レート制限を超えました。`Retry-After` の期間が経過してから再試行してください。 |
| 503 | `service_unavailable` | 依存先が一時的に利用できません。`Retry-After` の期間が経過してから再試行してください。 |

## 例

```bash
curl -i -X POST "https://api.eu.keenauth.com/v1/invitations:batch" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 0f6c1d2e3a4b5c6d7e8f9a0b" \
  -d '{"items":[{"organization_id":"org_01j9xk3m7q8r2s4t6v8w0y2z4a","email":"ada@example.com","delivery":"link_only"},{"organization_id":"org_01j9xk3m7q8r2s4t6v8w0y2z4a","email":"bob@example.com","delivery":"link_only"}]}'
```

## 個人データ

このエンドポイントは個人データ（組織のメンバーシップと招待）を扱います。[KeenAuth API における個人データ](/docs/policies/personal-data)では、保存される内容、保持期間、削除方法を説明しています。いずれのフィールドにも、特別な種類の個人データ（健康、生体情報、宗教、政治的意見、性的指向）を送信しないでください。
