予約管理API(Reservations API)の使い方
予約管理API(/api/v1/reservations)で、店舗の予約の取得・作成・変更・ステータス更新・時間変更、予約枠の取得・作成・一括生成・削除、メニューと開始可能時刻、店舗の予約設定、席(テーブル・個室など)、月次の予約件数を扱う方法をまとめています。どのエンドポイントも店舗単位で、storeId が必須です。予約を読むだけの連携を最短で作る手順は 店舗の予約を自社のカレンダーに表示する をご覧ください。
必要なスコープと権限
| スコープ | 使えるエンドポイント |
|---|---|
store.reservations.read | GET のすべて(予約・予約枠・予約設定・席・メニュー・開始可能時刻・件数) |
store.reservations.write | POST / PUT / DELETE のすべて(予約の作成・変更・時間変更、予約枠の作成・一括生成・削除) |
スコープはアプリの API スコープでチェックを入れ、認可 URL の scope に含めてください。スコープが足りない場合は 403 が返ります。
- ビジネスアカウントに紐付いたトークン(アプリの既定)は、そのビジネスアカウントのすべての店舗を扱えます。
organizationIdは不要です。別のビジネスアカウントのorganizationIdを付けると403になります。 - ユーザーとして動くトークンでは、すべての呼び出しにクエリ
?organizationId=を付けてください。そのユーザーの権限が適用され、店舗ごとのロールで判断する場合、読み取りにはスタッフ以上、書き込みにはシフトリーダー以上が必要です。
店舗IDは先に確認してください
予約一覧・予約枠・メニュー・件数の取得は、storeId が間違っていても、ほかのビジネスアカウントの店舗であっても、エラーにならず 200 で空の結果(件数は 0)を返します。「予約が0件」と「店舗IDの誤り」を区別できないため、店舗IDは次の方法で取得したものを使ってください。
- ユーザーとして動くトークン:
GET /api/v1/me/organizations/{organizationId}/storesで店舗一覧を取得します。 - ビジネスアカウントに紐付いたトークン:店舗一覧を返す API はありません。管理画面の予約管理の URL(
/organizations/{organizationId}/stores/{storeId}/reservations)から店舗IDを確認してください。
確認には GET /api/v1/reservations/tables?storeId= が使えます。このエンドポイントは、店舗がそのビジネスアカウントにない場合 404 を返します。
エンドポイント一覧
| メソッド | パス | 内容 |
|---|---|---|
| GET | /api/v1/reservations | 予約一覧(status・from・to で絞り込み) |
| GET | /api/v1/reservations/{reservationId} | 予約1件 |
| POST | /api/v1/reservations | 予約の作成 |
| PUT | /api/v1/reservations/{reservationId} | ステータス・お客様情報・メモなどの変更 |
| POST | /api/v1/reservations/{reservationId}/move | 別の予約枠への時間変更 |
| GET | /api/v1/reservations/slots | 予約枠一覧 |
| POST | /api/v1/reservations/slots | 予約枠を1件作成 |
| POST | /api/v1/reservations/slots/generate | 予約設定から予約枠を一括生成 |
| DELETE | /api/v1/reservations/slots/{slotId}?storeId= | 予約枠の削除 |
| GET | /api/v1/reservations/config | 店舗の予約設定 |
| GET | /api/v1/reservations/tables | 店舗レイアウトの予約できる席 |
| GET | /api/v1/reservations/menus | 予約メニュー一覧 |
| GET | /api/v1/reservations/menus/{menuId}/availability | メニューを開始できる時刻 |
| GET | /api/v1/reservations/stats | 1か月分のステータス別件数 |
GET と DELETE は storeId をクエリで、POST と PUT は JSON ボディで渡します。日付は yyyy-MM-dd、時刻は HH:mm です。予約の日付と時刻は店舗の現地時刻(日本時間)で、タイムゾーンは付きません。createdAt と updatedAt は UTC です。
予約のステータス
status は次の6つの文字列のいずれかです。大文字・小文字も含めてこのとおりに指定してください。
| 値 | 管理画面の表示 | 意味 |
|---|---|---|
Pending | 未確定 | 店舗がまだ確定していない予約。席は押さえています |
Confirmed | 確定 | 確定済みで、来店を待っている予約 |
Arrived | 来店済 | お客様が来店し、まだ終わっていない状態(チェックイン) |
Completed | 完了 | 利用が終わった予約 |
Cancelled | キャンセル | キャンセルされた予約 |
NoShow | 無断キャンセル | 連絡なく来店しなかった予約 |
予約一覧と予約1件の取得
curl -s "https://receiptroller.io/api/v1/reservations?storeId={storeId}&from=2026-11-01&to=2026-11-07" \
-H "Authorization: Bearer {access_token}"
storeIdは必須です。省略すると400({"error":"storeId is required"})です。fromとtoは予約日の範囲で、両端を含みます。省略すると日付で絞り込みません。statusは上の6つのうち1つを指定します。複数は指定できません。- 予約日・開始時刻の早い順に並びます。ページングはなく、条件に合う予約がすべて返ります。期間を区切って取得してください。
{
"count": 1,
"reservations": [
{
"id": "{reservationId}",
"storeId": "{storeId}",
"slotId": "{slotId}",
"reservationDate": "2026-11-03",
"startTime": "18:00",
"endTime": "19:00",
"durationMinutes": 60,
"status": "Confirmed",
"customerId": "",
"passId": "",
"paymentStatus": "None",
"paidAmount": 0,
"paidAt": null,
"customer": { "name": "山田 太郎", "phone": "090-0000-0000", "email": "" },
"partySize": 4,
"partySizeFields": {},
"customFields": {},
"assignedResource": "テーブル1",
"notes": { "customer": "窓際の席を希望", "staff": "" },
"cancellationReason": "",
"price": 0,
"currency": "JPY",
"bookingSource": "API",
"createdAt": "2026-10-26T03:12:45Z",
"updatedAt": "2026-10-26T03:12:45Z"
}
]
}
- メモは
notes.customer(お客様からの要望)とnotes.staff(店舗のメモ)の2つです。 customFieldsは店舗の予約フォームの追加項目への回答です。partySizeFieldsは同じ内容の古い名前で、既存のクライアントのために残しています。assignedResourceは割り当てられた席・部屋・スタッフの名前です(ID ではありません)。paymentStatusはNone/Paid/CardRegistered/Refunded/PartiallyRefundedのいずれかです。
予約1件は GET /api/v1/reservations/{reservationId}?storeId={storeId} で取得します。その店舗にない予約は 404 です。
予約の作成
curl -s -X POST "https://receiptroller.io/api/v1/reservations" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"storeId": "{storeId}",
"slotId": "{slotId}",
"reservationDate": "2026-11-03",
"startTime": "18:00",
"endTime": "19:00",
"durationMinutes": 60,
"customerName": "山田 太郎",
"customerPhone": "090-0000-0000",
"customerEmail": "",
"partySize": 4,
"customerNotes": "窓際の席を希望",
"staffNotes": ""
}'
- 必須は
storeIdとcustomerNameです。どちらかがないと400です。 slotIdを指定すると、その予約枠の空きを確保してから予約を保存します。slotIdを指定しても日付と時刻は予約枠から写されないため、reservationDate・startTime・endTimeも送ってください。- 予約枠に空きがない、または受付停止中の場合は
409で、予約は作られません。本文は{"error":"slot_unavailable","reason":"Full","message":"…"}の形で、reasonはFull(満席)・Closed(受付停止)・Contention(同時に予約が集中した)のいずれかです。別の予約枠で取り直してください。 statusは指定できません。店舗の予約設定で自動確定が有効ならConfirmed、無効ならPendingになります。bookingSourceを省略するとAPIが記録されます。- お客様メモは
customerNotes、店舗のメモはstaffNotesです。予約フォームの追加項目はcustomFieldsJsonに JSON 文字列で渡します(例:"{\"dietary\":\"えびアレルギー\"}")。 - 予約枠を指定しない予約(電話予約の記録など)も作れます。この場合、予約枠の空きは確保されません。
API で作成・変更した予約について、お客様への確認メールやキャンセルメール、店舗スタッフへの通知は送られません。お客様へのご連絡が必要な場合は、連携先のシステムから行ってください。
所要時間のあるメニューの予約
カットとカラーのように所要時間が違うメニューを扱う店舗では、先に開始可能な時刻を取得します。
curl -s "https://receiptroller.io/api/v1/reservations/menus/{menuId}/availability?storeId={storeId}&date=2026-11-03&partySize=1" \
-H "Authorization: Bearer {access_token}"
{
"menuId": "{menuId}",
"menuName": "カット+カラー",
"durationMinutes": 90,
"date": "2026-11-03T00:00:00",
"count": 1,
"startTimes": [
{
"startTime": "10:00",
"endTime": "11:30",
"staffId": "{staffId}",
"assignedResource": "佐藤",
"primarySlotId": "{slotId1}",
"joinedSlotIds": ["{slotId2}", "{slotId3}"]
}
]
}
date は必ず指定してください。メニューが見つからないか停止中の場合は 404 です。返る時刻は、所要時間分の予約枠が同じ席またはスタッフで連続して空いているものだけです。
予約するときは、slotId に primarySlotId を、joinedSlotIds に残りの予約枠IDを、menuId にメニューIDを入れて POST /api/v1/reservations を呼びます。
{
"storeId": "{storeId}",
"menuId": "{menuId}",
"slotId": "{slotId1}",
"joinedSlotIds": "{slotId2},{slotId3}",
"reservationDate": "2026-11-03",
"startTime": "10:00",
"endTime": "11:30",
"durationMinutes": 90,
"customerName": "山田 花子"
}
- 開始可能時刻の応答では
joinedSlotIdsは配列ですが、予約作成ではカンマ区切りの文字列で送ります。配列のまま送ると400になります。 menuIdを省略してjoinedSlotIdsを送ると、テーブルを組み合わせた予約として扱われ、各予約枠を丸ごと押さえます。メニューの予約では必ずmenuIdを付けてください。- メニュー名や料金はメニューから自動では入りません。必要なら
menuNameとpriceも送ってください。
メニュー一覧は GET /api/v1/reservations/menus?storeId= で取得します。既定では受付中のメニューだけを返し、includeInactive=true で停止中も含めます。各メニューには menuId・name・durationMinutes・bufferMinutes・price・isActive・visibility などが含まれます。visibility は数値で、0 が公開、1 が一覧に表示しない、2 が会員限定です。予約メニューを使っていない店舗では空の一覧が返ります。
予約の変更とステータスの更新
PUT /api/v1/reservations/{reservationId} は、ボディに含めた項目だけを変更します。含めなかった項目はそのまま残ります。空文字列を送るとその項目を空にします。
curl -s -X PUT "https://receiptroller.io/api/v1/reservations/{reservationId}" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{ "storeId": "{storeId}", "status": "Arrived" }'
変更できる項目は status・cancellationReason・customerName・customerPhone・customerEmail・customerNotes・staffNotes・assignedResource・customFields です。storeId は必須です。customFields はオブジェクトで送り、回答全体を置き換えます。日付・時刻・人数はこのエンドポイントでは変更できません。時間を変えるときは次の「予約の時間変更」を使ってください。
変更できるステータス
Arrivedにできるのは、PendingかConfirmedの予約だけです。Cancelled・NoShow・Completedの予約は、Pending・Confirmed・Arrivedに戻せません。席はすでに解放されているため、予約を取り直してください。Cancelled・NoShow・Completedの間の訂正はできます。- 許可されない変更は
409({"error":"invalid_transition","message":"…"})、6つ以外の値は400です。
ステータス変更で起きること
- 席を押さえている予約を
CancelledまたはNoShowにすると、予約枠の席が戻ります。 Cancelledのときは、キャンセル待ちを受け付けている店舗では待っている方へのご案内が行われ、回数券を使った予約では回数が返却されます。cancellationReasonを送るとキャンセル理由として記録されます。- 管理画面で行う確認・キャンセルメールの送信、無断キャンセル料の請求、返金は、API からのステータス変更では行われません。
予約の時間変更
curl -s -X POST "https://receiptroller.io/api/v1/reservations/{reservationId}/move" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{ "storeId": "{storeId}", "slotId": "{newSlotId}" }'
お客様情報・メモ・回数券・支払い状況はそのままに、予約を別の予約枠へ移します。日付・時刻・担当の席やスタッフは移動先の予約枠のものになります。新しい予約枠を確保してから元の予約枠を解放するため、途中で満席になった場合は予約は元のままです。
- メニューの予約は、
slotId(移動先のprimarySlotId)から必要な分の予約枠が自動で押さえられます。 - テーブルを組み合わせた予約は、
joinedSlotIds(こちらは配列)を指定するか、省略して自動で席を割り当てます。 - 移せるのは
PendingとConfirmedの予約だけです。それ以外は409invalid_transition、宿泊・レンタルの予約は409not_movable、移動先の予約枠がない場合は404slot_not_found、満席などで移せない場合は409slot_unavailableです。
予約枠の取得
curl -s "https://receiptroller.io/api/v1/reservations/slots?storeId={storeId}&from=2026-11-03&to=2026-11-03" \
-H "Authorization: Bearer {access_token}"
{
"count": 1,
"slots": [
{
"id": "{slotId}",
"storeId": "{storeId}",
"date": "2026-11-03",
"startTime": "18:00",
"endTime": "19:00",
"durationMinutes": 60,
"capacity": 4,
"capacityUnit": "Seats",
"bookedCount": 0,
"remainingCapacity": 4,
"isAvailable": true,
"assignedResource": "テーブル1",
"resourceCategory": "テーブル",
"price": 0,
"status": "Available",
"notes": ""
}
]
}
fromとtoは両端を含みます。fromを省略すると今日(UTC の日付)、toを省略するとfromの7日後です。日本時間の午前0時から9時の間は UTC の日付が前日になるため、日付は明示して指定することをおすすめします。capacityUnitがBookingsの予約枠は1件の予約で1、Seatsの予約枠は1件の予約で人数分の空きを使います。- 予約を受けられるかどうかは
isAvailableで判断してください。
予約枠の作成と削除
curl -s -X POST "https://receiptroller.io/api/v1/reservations/slots" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"storeId": "{storeId}",
"slotDate": "2026-11-03",
"startTime": "18:00",
"endTime": "19:00",
"durationMinutes": 60,
"capacity": 4,
"capacityUnit": "Seats",
"assignedResource": "テーブル1"
}'
- 必須は
storeId・slotDate・startTime・endTimeです。 capacityの既定は1、capacityUnitの既定はBookingsです。durationMinutesは時刻から計算されないため、送ってください。assignedResourceには席・部屋・スタッフの名前を入れます。スタッフの予約枠ではstaffIdも指定できます。ほかにresourceCategory・price・notesを指定できます。
削除は DELETE /api/v1/reservations/slots/{slotId}?storeId={storeId} で、成功すると 204 を返します。予約が入っている予約枠も削除され、その予約枠の予約は残ったままになります。削除の前に予約一覧で確認してください。
予約枠の一括生成
curl -s -X POST "https://receiptroller.io/api/v1/reservations/slots/generate" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{ "storeId": "{storeId}", "from": "2026-11-01", "to": "2026-11-30", "perResource": false }'
{ "created": 270 }
店舗の予約設定の営業時間・定休日・枠の長さをもとに、from から to まで(両端を含む)の予約枠を作り、作成した件数を返します。to が from より前なら 400 です。
perResource: false:枠の長さはdefaultSlotDurationMinutes、定員はmaxConcurrentBookings、単位はslotCapacityUnitです。同じ日・同じ開始時刻の予約枠がすでにあれば作りません。営業時間設定で臨時休業にした日も飛ばします。perResource: true:店舗レイアウトの予約できる席(テーブル・個室・カウンター・席/ブース)ごとに予約枠を作ります。定員はその席の人数で、単位はSeats、assignedResourceは席の名前です。同じ日・同じ開始時刻・同じ席の予約枠があれば作りません。予約できる席が1つもない場合は400です。- 予約設定がまだない店舗では
{"created":0}を返します。 - 予約設定に営業時間がない場合は、月曜から土曜の 10:00〜19:00 で生成し、その営業時間を予約設定に保存します。
店舗の予約設定
GET /api/v1/reservations/config?storeId= は、管理画面の予約設定の内容を返します。予約設定がまだない店舗では 404 です。予約画面を作るときによく使う項目は次のとおりです。
| 項目 | 内容 |
|---|---|
storeType | 店舗の業種 |
defaultSlotDurationMinutes | 予約枠の長さ(分) |
maxConcurrentBookings / slotCapacityUnit | 1枠の定員と、その単位(Bookings または Seats) |
bookingWindowDays / minAdvanceHours | 何日先まで受け付けるか、何時間前まで受け付けるか |
cancellationDeadlineHours | お客様がご自身でキャンセルできる期限(開始の何時間前か。0 は期限なし) |
autoConfirm | 新しい予約を自動で確定するか |
businessHours | mon〜sun をキーにした営業時間(open・close・closed・ranges) |
closedDayList | 定休日(mon などの配列) |
customFields | 予約フォームの追加項目(key・label・type・required・options・placeholder) |
このほかの項目は API リファレンス をご覧ください。予約設定の変更は管理画面で行います。
席(テーブル)の取得
GET /api/v1/reservations/tables?storeId= は、店舗レイアウトで予約できる席を返します。店舗がそのビジネスアカウントにない場合は 404 です。
{
"count": 2,
"tables": [
{ "id": "{itemId}", "name": "個室A", "type": "room", "typeDisplayName": "個室", "capacity": 8 },
{ "id": "{itemId}", "name": "テーブル1", "type": "table", "typeDisplayName": "テーブル", "capacity": 4 }
]
}
typeはtable・room・counter・stationのいずれかです。typeDisplayNameは日本語の表示名です。- 予約枠や予約の
assignedResourceには、ここで返るnameが入ります。idではありません。 - 予約を担当できるスタッフも含めて取得する場合は
GET /api/v1/reservations/resourcesを使います。 - 席の配置は管理画面のレイアウトエディタで編集します。
月次の予約件数
curl -s "https://receiptroller.io/api/v1/reservations/stats?storeId={storeId}&month=2026-11-01" \
-H "Authorization: Bearer {access_token}"
{
"totalReservations": 42,
"confirmed": 20,
"pending": 3,
"arrived": 1,
"completed": 12,
"cancelled": 5,
"noShow": 1,
"todayCount": 4,
"tomorrowCount": 6
}
monthにはその月の任意の日付を指定します。省略すると今月です。todayCountとtomorrowCountは、今日と明日の予約のうちPending・Confirmed・Arrivedの件数です。今日と明日は UTC の日付で判定し、指定した月の予約だけを数えます。- 任意の期間の集計や売上・リピート率は、在庫・リソース・予約分析API の予約分析を使ってください。
エラーの形
401:トークンがない、無効、または期限切れ。本文はありません。403:スコープが足りない、権限がない、または別のビジネスアカウントのorganizationIdを指定した。本文はありません。400/404/409:{"error":"…"}の形で、messageやreasonが付くことがあります。messageは日本語の場合があります。判定にはerrorとreasonを使ってください。
予約の作成・変更を知らせる Webhook イベントはありません。変更を取り込む場合は、予約一覧を期間を区切って定期的に取得してください。
関連ガイド
-
店舗情報API(Store Information API)の使い方店舗の基本情報(店舗名・店舗種別・連絡先・住所)を取得・更新する REST API のガイドです。スタッフアプリなどのトークン認証クライアントから店舗情報の編集を実装できます。
-
定期予約・出欠・キャンセル待ちAPI の使い方レシートローラーの定期予約API(/api/v1/reservations/series)、出欠・振替API(/api/v1/reservations/attendance)、キャンセル待ちAPI(/api/v1/reservations/waitlist)のガイドです。毎週の定期予約の登録と生成、クラスの出欠記録、振替の受付、キャンセル待ちの管理を解説します。
-
営業時間API(Business Hours API)の使い方レシートローラーの営業時間API(/api/v1/stores/{storeId}/business-hours)のガイドです。曜日ごとの営業時間の取得・更新、特例営業日(臨時休業・営業時間変更)の登録、店舗の就業可能時間(シフト作成時の上限となる業務時間)の設定、現在営業中かどうかの判定までを解説します。
-
リクエストとレスポンスの基本(JSON)レシートローラーAPIのリクエスト形式、必須ヘッダー、レスポンス構造、ページネーション、フィルタリング、日時形式の規則を解説します。
-
ネイティブモバイルアプリ向けガイド: 複数ビジネスアカウントアクセスと OAuth フローAndroid / iOS のネイティブアプリ向け実装ガイド。アプリ登録時に「認可時に1つのビジネスアカウントへトークンを紐付ける」をオフにすると、user-scoped OAuth トークンが発行されます。/api/v1/me/organizations + ?organizationId= パターンで複数ビジネスアカウントを横断アクセスできます。