コンテンツにスキップ

予約を作成する

自社サイトの予約フォームからタスクルに予約を入れる、という流れを例に説明します。

1. 商品を取得する GET /products
2. 空き状況を取得する GET /products/{id}/availability
3. 料金を計算して提示する POST /reservations/calculate
4. 予約を作成する POST /reservations

以下、{storeId} は店舗ID、ベースURLは https://api.tascrew.com/v1/public/stores/{storeId} です。

Terminal window
curl "$BASE/products" -H "Authorization: Bearer $KEY"

isPublished が false の商品も返ります。 これは非公開の商品で連携を試せるようにするためです。お客様に見せる画面では isPublished で絞り込んでください。

approvalType を必ず確認してください。

値予約作成時の挙動
instant予約はすぐに確定します(confirmed)
manual承認待ちになります(pending)

manual の商品で「ご予約が確定しました」とお客様に伝えてしまわないよう注意してください。

manual の商品を予約したときにタスクルが送る確認メールには、件名に 【承認待ち】 が付き、まだ確定していないことが本文にも書かれます。事業者が管理画面で承認すると、あらためて承認完了メールが届きます。

予約に必要な入力項目を調べる

Section titled “予約に必要な入力項目を調べる”

商品詳細を取得すると customFields が入っています。これがお客様に入力してもらう項目の定義です。

Terminal window
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必須かどうか。埋めないと予約作成が失敗します
inputScopebooker_only は代表者だけ、all_participants は参加者全員分が必要
options選択肢(select / multi_select のとき)
validation数値の範囲や文字数の制限
Terminal window
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 で確認できます。

お客様に金額を提示する前に、必ずこれを通してください。グループ割引やリピート割引が適用された金額が返ります。

Terminal window
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"
}'
Terminal window
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"
}'

リクエストごとに一意な値(UUID など)を付けてください。

通信のエラーで再送したときに、予約が二重に入るのを防ぐためのものです。同じキーで同じ内容を送ると、予約は増えず、最初の結果がそのまま返ります。

状況応答
同じキー・同じ内容201 と最初の予約(新しく作られません)
同じキー・違う内容409 IDEMPOTENCY_KEY_REUSED
同じキーで処理中409 REQUEST_IN_PROGRESS(少し待って再試行)

予約ごとに新しいキーを生成してください。 使い回すと2件目以降が作れません。

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 で弾かれます(黙って捨てると、送っているのに受付シートに出ない、という分かりにくい状態になるためです)

予約を取得すると、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 で決まります(省略時は日本語)。

自社システムで顧客を管理している場合は、customerId を渡すと確実に同じお客様に紐づきます。メールアドレスの表記ゆれで別の顧客が増えるのを防げます。

顧客IDは GET /customers?email=... で調べられます(「顧客の検索」の権限が必要です)。

{ "customerId": "cust_xxxxx", "customer": { "...": "..." } }

customerId を渡した場合、リピート割引はその顧客のメールアドレスで計算されます(customer.email は無視されます)。

予約を作るだけでは、自社システムとタスクルの状態は一致しません。 タスクル側でキャンセルや変更が行われても、作成しかしていないシステムはそれを知る手段がないためです。

定期的に予約一覧を取得して、変更を取り込んでください。

Terminal window
curl "$BASE/reservations?updatedSince=2026-08-14T00:00:00.000Z&limit=100" \
-H "Authorization: Bearer $KEY"

updatedSince に前回の同期時刻を渡すと、それ以降に更新された予約だけが返ります。並びは更新日時の昇順です。

{ "data": [ ... ], "nextCursor": "eyJ..." }

nextCursor が null でなければ続きがあります。次のリクエストに cursor としてそのまま渡してください。中身を解釈したり組み立てたりしないでください。

Terminal window
curl "$BASE/reservations?cursor=eyJ..." -H "Authorization: Bearer $KEY"

キャンセル料はキャンセルポリシーによって決まります。外部からは再現できないので、お客様に金額を伝える前に必ず試算してください。

Terminal window
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 を呼びます(本文は同じです)。

refundHandledBy を確認してください。

値意味
tascrewタスクルが自動で返金します
merchant事業者側で返金してください。 タスクルからは返金されません

on_site(現地払い)と external(外部決済)は merchant になります。現地払いはまだ受け取っていないので通常は何もしませんが、external は外部の決済で受け取っているため、refundAmount の額をご自身で返金する必要があります。

なお refundAmount は総額からキャンセル料を引いた額で、外部の決済業者の手数料は差し引いていません(タスクルからは知り得ないためです)。

値キャンセル料
customer_request発生します
business_request発生しません
weather発生しません
force_majeure発生しません

キャンセルすると、お客様と事業者にキャンセル通知メールが送られます。予約作成時の確認メールと同じ扱いです。

連携元のシステムで独自に通知している場合は sendCancellationEmail: false を指定してください。予約作成の sendConfirmationEmail と対になる指定です。

{
"cancelReason": "business_request",
"sendCancellationEmail": false
}