予約を作成する
自社サイトの予約フォームからタスクルに予約を入れる、という流れを例に説明します。
1. 商品を取得する GET /products2. 空き状況を取得する GET /products/{id}/availability3. 料金を計算して提示する POST /reservations/calculate4. 予約を作成する POST /reservations以下、{storeId} は店舗ID、ベースURLは https://api.tascrew.com/v1/public/stores/{storeId} です。
1. 商品を取得する
Section titled “1. 商品を取得する”curl "$BASE/products" -H "Authorization: Bearer $KEY"isPublished が false の商品も返ります。 これは非公開の商品で連携を試せるようにするためです。お客様に見せる画面では isPublished で絞り込んでください。
approvalType を必ず確認してください。
| 値 | 予約作成時の挙動 |
|---|---|
instant | 予約はすぐに確定します(confirmed) |
manual | 承認待ちになります(pending) |
manual の商品で「ご予約が確定しました」とお客様に伝えてしまわないよう注意してください。
manual の商品を予約したときにタスクルが送る確認メールには、件名に 【承認待ち】 が付き、まだ確定していないことが本文にも書かれます。事業者が管理画面で承認すると、あらためて承認完了メールが届きます。
予約に必要な入力項目を調べる
Section titled “予約に必要な入力項目を調べる”商品詳細を取得すると customFields が入っています。これがお客様に入力してもらう項目の定義です。
curl "$BASE/products/prod_xxx" -H "Authorization: Bearer $KEY"{ "product": { "customFields": [ { "fieldId": "cf_xxxxx", "label": "身長", "fieldType": "number", "isRequired": true, "inputScope": "all_participants", "options": null, "validation": { "min": 100, "max": 200 } } ] }}| 項目 | 意味 |
|---|---|
fieldId | 予約作成時にキーとして使う値 |
label | フォームに表示する項目名 |
isRequired | 必須かどうか。埋めないと予約作成が失敗します |
inputScope | booker_only は代表者だけ、all_participants は参加者全員分が必要 |
options | 選択肢(select / multi_select のとき) |
validation | 数値の範囲や文字数の制限 |
2. 空き状況を取得する
Section titled “2. 空き状況を取得する”curl "$BASE/products/prod_xxx/availability?year=2026&month=9" \ -H "Authorization: Bearer $KEY"日ごとに status と時間枠が返ります。available または limited なら予約できます。
status が示す条件は予約作成にもそのまま適用されます。 closed(営業日外・除外日・定休日)、past(過去日)、deadline_passed(締切超過)の日に予約を作ると SLOT_NOT_AVAILABLE が返ります。空き状況で予約できない日は、予約作成でも受け付けません。
予約締切は時間帯ごとに設定できます。締切を過ぎた時間帯はその日の slots に含まれず、その日の全時間帯が締切を過ぎたときに status が deadline_passed になります。slots に無い時間帯で予約を作ると SLOT_NOT_AVAILABLE が返ります。日ごとの時間帯は事業者の設定(開催パターンや特定日の追加・休止)で変わるので、時刻を固定で持たず、必ずこの slots から選んでください。
remainingCapacity は、スタッフや車両といった共有リソースの制約も反映した残席です。ただし予約作成時に改めて確認されるので、ここでの値は目安として扱ってください。取得してから作成するまでの間に、他のお客様の予約が入ることがあります。
時間帯に無い時刻を送ると TIME_SLOT_NOT_FOUND(400)が返ります。満席(SLOT_NOT_AVAILABLE)とは別のコードです——満席なら別の枠を探しますが、こちらは送っている時刻そのものを見直す必要があるためです。開催時刻をご自身のシステムで決めている場合は、商品の設定で「外部システム(API)からの予約は上の時間帯に無い時刻も受け付ける」をオンにしてください。終了時刻は商品の所要時間から決まります。設定の状態は商品詳細の unlistedTimeAllowedForApi で確認できます。
締切を過ぎた時間帯は slots から消え、予約も作成できません。締切の判断をご自身のシステムで行っている場合は、商品の設定で「外部システム(API)からの予約には締切を適用しない」をオンにしてください。オンの商品は、空き状況・予約作成のどちらも締切(時間帯ごとの上書きを含む)を見なくなります(お客様向けの予約ページは締切どおりのままです)。設定の状態は商品詳細の bookingDeadline.ignoredForApi で確認できます。
3. 料金を計算する
Section titled “3. 料金を計算する”お客様に金額を提示する前に、必ずこれを通してください。グループ割引やリピート割引が適用された金額が返ります。
curl -X POST "$BASE/reservations/calculate" \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -d '{ "items": [{ "productId": "prod_xxx", "date": "2026-09-15", "startTime": "10:00", "adultCount": 2, "childCount": 0 }], "customerEmail": "customer@example.com" }'4. 予約を作成する
Section titled “4. 予約を作成する”curl -X POST "$BASE/reservations" \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 8f14e45f-ea0d-4f1b-9a1e-2d3c4b5a6978" \ -d '{ "customer": { "lastName": "山田", "firstName": "太郎", "email": "customer@example.com", "phone": "09012345678" }, "items": [{ "productId": "prod_xxx", "date": "2026-09-15", "startTime": "10:00", "adultCount": 2, "childCount": 0, "participants": [ { "participantNumber": 1, "fieldValues": { "cf_xxxxx": 170 } }, { "participantNumber": 2, "fieldValues": { "cf_xxxxx": 165 } } ] }], "paymentMethod": "on_site" }'Idempotency-Key は必須です
Section titled “Idempotency-Key は必須です”リクエストごとに一意な値(UUID など)を付けてください。
通信のエラーで再送したときに、予約が二重に入るのを防ぐためのものです。同じキーで同じ内容を送ると、予約は増えず、最初の結果がそのまま返ります。
| 状況 | 応答 |
|---|---|
| 同じキー・同じ内容 | 201 と最初の予約(新しく作られません) |
| 同じキー・違う内容 | 409 IDEMPOTENCY_KEY_REUSED |
| 同じキーで処理中 | 409 REQUEST_IN_PROGRESS(少し待って再試行) |
予約ごとに新しいキーを生成してください。 使い回すと2件目以降が作れません。
参加者の情報
Section titled “参加者の情報”participants は商品の customFields に従って検証されます。不備があると 400 が返り、どの参加者のどの項目が問題かが details に入ります。
{ "error": "参加者情報に不備があります", "code": "PARTICIPANT_VALIDATION_FAILED", "details": [ { "participantNumber": 2, "fieldId": "cf_xxxxx", "label": "身長", "code": "MISSING_REQUIRED_FIELD", "reason": "必須項目です" } ]}主なポイントです。
participantNumberは 1 から始まる連番で、重複してはいけません。1 が代表者ですinputScopeがall_participantsの必須項目があるときは、参加人数分のparticipantsが必要です- 商品に定義されていない項目を送ると
UNKNOWN_FIELDで弾かれます(黙って捨てると、送っているのに受付シートに出ない、という分かりにくい状態になるためです)
送った内容は読み返せます
Section titled “送った内容は読み返せます”予約を取得すると、items[].participants に送ったときと同じ形で入っています。一覧(GET /reservations)でも返るので、差分同期のたびに1件ずつ取り直す必要はありません。
{ "participants": [ { "participantNumber": 1, "fieldValues": { "cf_xxxxx": "170" } }, { "participantNumber": 2, "fieldValues": { "cf_xxxxx": "165" } } ]}select の項目には選択肢の value(option_1 など)が入ります。表示名は GET /products/{productId} の customFields から引いてください。
参加者情報を送っていない予約では、participants は空配列です(null にはなりません)。
指定できるのは次の2つです。
| 値 | 意味 |
|---|---|
on_site | 現地払い。当日お客様から受け取ります |
external | タスクルの外で決済が完了している(自社サイトの決済など) |
タスクル上でのカード決済は API からは行えません。 カード決済をご希望のお客様は、タスクルの予約サイトへ誘導してください。
external は、自社サイト側で決済を済ませた予約を取り込むためのものです。店舗の決済設定に関わらず使えます。売上として集計されますが、返金はタスクルから実行できません(後述)。
予約を作ると、お客様と事業者に予約確認メールが送られます。内容も差出人も、タスクルの予約サイトから入った予約とまったく同じです。文面は管理画面のメールテンプレートで編集できます。
自社サイト側で独自の確認メールを送っている場合は、sendConfirmationEmail に false を指定してください。
{ "sendConfirmationEmail": false, "customer": { "...": "..." } }| 値 | 動作 |
|---|---|
省略 / true | お客様と事業者に予約確認メールを送る(既定) |
false | 予約確認メールを送らない |
false にしても、前日・当日のリマインダーと体験翌日のレビュー依頼メールは送られます。 これらは事業者ごとの設定に従うもので、予約の作られ方では変わりません。止めたい場合は管理画面の設定で切ってください。
メールの言語は locale で決まります(省略時は日本語)。
既存のお客様に紐づける
Section titled “既存のお客様に紐づける”自社システムで顧客を管理している場合は、customerId を渡すと確実に同じお客様に紐づきます。メールアドレスの表記ゆれで別の顧客が増えるのを防げます。
顧客IDは GET /customers?email=... で調べられます(「顧客の検索」の権限が必要です)。
{ "customerId": "cust_xxxxx", "customer": { "...": "..." } }customerId を渡した場合、リピート割引はその顧客のメールアドレスで計算されます(customer.email は無視されます)。
変更を取り込む
Section titled “変更を取り込む”予約を作るだけでは、自社システムとタスクルの状態は一致しません。 タスクル側でキャンセルや変更が行われても、作成しかしていないシステムはそれを知る手段がないためです。
定期的に予約一覧を取得して、変更を取り込んでください。
curl "$BASE/reservations?updatedSince=2026-08-14T00:00:00.000Z&limit=100" \ -H "Authorization: Bearer $KEY"updatedSince に前回の同期時刻を渡すと、それ以降に更新された予約だけが返ります。並びは更新日時の昇順です。
ページの続きを取る
Section titled “ページの続きを取る”{ "data": [ ... ], "nextCursor": "eyJ..." }nextCursor が null でなければ続きがあります。次のリクエストに cursor としてそのまま渡してください。中身を解釈したり組み立てたりしないでください。
curl "$BASE/reservations?cursor=eyJ..." -H "Authorization: Bearer $KEY"キャンセルする
Section titled “キャンセルする”キャンセル料はキャンセルポリシーによって決まります。外部からは再現できないので、お客様に金額を伝える前に必ず試算してください。
curl -X POST "$BASE/reservations/resv_xxx/cancel-preview" \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -d '{ "cancelReason": "customer_request" }'{ "cancellable": true, "totalAmount": 10000, "cancellationFee": 3000, "refundAmount": 7000, "refundHandledBy": "merchant"}問題なければ cancel を呼びます(本文は同じです)。
返金は誰が行うか
Section titled “返金は誰が行うか”refundHandledBy を確認してください。
| 値 | 意味 |
|---|---|
tascrew | タスクルが自動で返金します |
merchant | 事業者側で返金してください。 タスクルからは返金されません |
on_site(現地払い)と external(外部決済)は merchant になります。現地払いはまだ受け取っていないので通常は何もしませんが、external は外部の決済で受け取っているため、refundAmount の額をご自身で返金する必要があります。
なお refundAmount は総額からキャンセル料を引いた額で、外部の決済業者の手数料は差し引いていません(タスクルからは知り得ないためです)。
キャンセル理由
Section titled “キャンセル理由”| 値 | キャンセル料 |
|---|---|
customer_request | 発生します |
business_request | 発生しません |
weather | 発生しません |
force_majeure | 発生しません |
キャンセル通知メール
Section titled “キャンセル通知メール”キャンセルすると、お客様と事業者にキャンセル通知メールが送られます。予約作成時の確認メールと同じ扱いです。
連携元のシステムで独自に通知している場合は sendCancellationEmail: false を指定してください。予約作成の sendConfirmationEmail と対になる指定です。
{ "cancelReason": "business_request", "sendCancellationEmail": false}