Auto Scheduler
料金プレイグラウンド使い方ブログよくある質問API ドキュメント
サインイン

このページの内容

概要対象範囲契約プランと請求認証LLM 用にコピーエンドポイント使い方(クイックスタート)MCP(エージェント連携)取得 API(GET)更新 API(PATCH / POST / PUT / DELETE)完了通知 Webhookヘッダ有料枠の上限ルートで許可されるキーリクエストボディ概要クイックリファレンス表フィールドリファレンス(許容値)apiVersiontimeZonescheduleStartDate / scheduleEndDatetimeRangeStart / timeRangeEndslotGranularityMinutesrequirementsByCellrequiredRolesByCellstaffavailableCellsstaff[].schedulingRoleIds / Soft prefer-avoid労働法・有料フラグ(サーバー既定)サニタイズ成功レスポンスエラーコード一覧JSON 例参照

Auto Scheduler

有料 API · 契約プラン

開発者向け API リファレンス

有料 REST API(スケジュール投入・スタッフ・営業既定・関連 GET)。API 管理で発行したキーを使います。請求は契約プランに従います(呼び出し従量ではありません)。サイドバーからエンドポイントとフィールドへジャンプできます。

このドキュメントの対象範囲

本ページが記載するのは、外部連携用の製品 REST API です。

スケジュール結果の完了通知 Webhook は、REST の CRUD ではなく、アカウントの API 管理画面で登録するアウトバウンド HTTP 通知です。ペイロードと署名の仕様は本ページの「完了通知 Webhook」を参照してください。

サイト内のブラウザ向けルート(例: 決済コールバックや計測用のパス)は、この製品 API の代替ではありません。外部システムからは本ページの /v1/* と完了通知 Webhook を利用してください。

契約プランとアクセス

本 HTTP API は有料プロダクトの一部です。利用には商用契約が有効であることと、オンボーディング後に組織向けにキーが発行されることを前提とします。

課金は契約プラン(サブスクリプション)に基づきます。有料プランの請求額は料金表に従い、登録スタッフ数(席)に比例する月額になり得ます。

プレイグラウンド/無料枠の制限は有料 API キーには適用されません。スケジュール日数・スタッフ数・15 分粒度の有効などは、有料エンタイトルメントで決まります。詳細は本ページの有料枠の上限を参照してください。

認証

有料契約に基づき発行された API キーをリクエストに含めてください。キーの作成・ローテーション・失効はサインイン後のアカウント画面から行えます。

キーは x-api-key ヘッダで送ります。キーは組織に紐づき、契約プランに基づく利用上限が適用されます。発行時に選んだ操作スコープ(scopes)が無い操作は 403(API_KEY_SCOPE_DENIED)になります。scopes 属性の無い既存キーは従来どおり全操作が許可されます。

キーの管理: API 管理

Auto Scheduler

スタッフのシフト最適化と自動スケジューリングを支援するクラウドサービス。希望や法令・現場ルールを踏まえ、公平で運用しやすい勤務表づくりをサポートします。

利用規約|プライバシーポリシー|特定商取引法に基づく表記

ソルバー

LLM 用にコピー

MCP を設定せずに、チャット型 LLM へこの製品 API の前提を渡したいときに、下のブロックを貼り付けてください。

ベース URL・認証・主要操作・書き込み時の注意を要約します。実 API キーは含めません(秘密は環境変数などだけに置いてください)。

エージェントから実際に API を呼ぶときは、この貼り付けだけでなく MCP(エージェント連携) を設定してください。

貼り付け用コンテキスト

Auto Scheduler — LLM 向け公開 API コンテキスト

開発者が Auto Scheduler の有料製品 REST API(/v1/*)を呼ぶのを手伝うときに使ってください。可能なら Tools MCP を優先し、この貼り付けは MCP が使えないチャット向けです。

ベース URL
- https://api.autoschedulers.com
- パスは /v1/* 配下。マーケティングサイトのオリジンと混同しないこと。

認証
- すべてのリクエストにヘッダ: x-api-key: <API_KEY>
- 実 API キーをチャットやこのプロンプトに貼らない。ユーザーに環境変数やシークレットストア経由で渡してもらう。
- キーはアカウント → API 管理で発行する。
- JSON 書き込み: Content-Type: application/json

読み取りエンドポイント
- GET /v1/schedule-results?limit=10
- GET /v1/schedule-results/{conditionId}
- GET /v1/schedule-conditions
- GET /v1/staff
- GET /v1/staff/{staffId}
- GET /v1/schedule-defaults
- GET /v1/schedule-results/{conditionId}/emergency-shift-context

書き込みエンドポイント(実行前にユーザー確認)
- POST /v1/schedule — ジョブ起動・課金の可能性・最大 14 カレンダー日
- PATCH /v1/schedule-defaults — テナント全体
- POST /v1/staff
- PATCH /v1/staff/{staffId}
- PUT /v1/staff/{staffId}/weekly-shift-wish — 全置換
- POST /v1/schedule-results/{conditionId}/emergency-shift — 有料
- POST /v1/schedule-results/{conditionId}/confirm-assignments
- DELETE /v1/schedule-conditions/{conditionId}
- PUT /v1/schedule-actual/{conditionId} — 全置換

最小 curl(読み取り)
curl -sS -H "x-api-key: YOUR_API_KEY" "https://api.autoschedulers.com/v1/staff"
curl -sS -H "x-api-key: YOUR_API_KEY" "https://api.autoschedulers.com/v1/schedule-results?limit=10"

契約メモ
- スケジュール提出 body は対応 apiVersion と許可フィールドが必要。詳細は api-docs のフィールドリファレンスまたは Docs MCP。フィールドを創作しない。
- 既定値の planningHorizon は week または two_weeks のみ(month_attendance は拒否)。
- 完了 Webhook は API 管理で設定する HMAC 付き HTTPS(REST CRUD ではない)。

安全
- 書き込みはテナントデータを変える。破壊的・不可逆な操作は実行前にユーザー確認を取る。
- 未知テナントではまず読み取り/一覧から。

エンドポイント

スケジュール条件を JSON で投入する有料向け連携面です。ベース URL は API アクセスが付与されたあと、環境ごとに案内されます。

ベース URL

公開 REST(/v1/*)のホストです。ブラウザのサイト URL ではありません。MCP の環境変数 AUTO_SCHEDULER_PUBLIC_API_BASE_URL と curl の BASE_URL には、この値を設定します。

AUTO_SCHEDULER_PUBLIC_API_BASE_URL — このドキュメント環境向けに設定されているベース URL です。MCP や curl にそのまま使えます。

AUTO_SCHEDULER_PUBLIC_API_BASE_URL=https://api.autoschedulers.com
https://api.autoschedulers.com
POST https://api.autoschedulers.com/v1/schedule

パスはベース URL のあとに続けます(例: {baseUrl}/v1/schedule)。末尾スラッシュの有無はどちらでも構いません。

使い方(クイックスタート)

**BASE_URL** には、開通時に案内された API のベース URL(パスのプレフィックス)を入れてください。

API キーは **x-api-key** ヘッダで送ります。キーに紐づく組織(テナント)が自動的に識別されるため、別途テナント ID をクエリで渡す必要はありません。

有料機能(緊急シフト・労務詳細・一部のスケジュール既定など)は有効な有料契約が必要です。契約が未設定・無効な場合は **503**(code: **STRIPE_NOT_CONFIGURED** 等)になることがあります。会社情報・監査ログ・ユーザー管理は Web アプリ管轄のため公開 API には含めません。

curl の例(bash / macOS / Linux / WSL)

Windows PowerShell: 行末の \ は **行継続になりません**。1 行で書くか、行末を **バッククォート(`)** で続けてください。

curl -sS -D - \
  -H "x-api-key: YOUR_API_KEY" \
  "https://api.autoschedulers.com/v1/schedule-results?limit=10"

curl -sS -D - \
  -H "x-api-key: YOUR_API_KEY" \
  "https://api.autoschedulers.com/v1/staff"

MCP(エージェント連携)

同じ製品 REST API を、Cursor / Claude / Gemini / GPT などのエージェントから MCP 経由で呼べます。呼び出す内容は本ページの /v1 と同じです。

本製品の MCP はローカル stdio です。各クライアントの設定ファイルに command / args / env を書きます。API キーは API 管理で発行してください(チャットやリポジトリに載せない)。

仕様の参照だけなら、認証不要のドキュメント MCP(Resources)もあります(mcp/api-docs)。本ページ(/{locale}/api-docs)もログインなしで閲覧できます。キー発行だけアカウントが必要です。

最短セットアップ(推奨)

  1. アカウント → API 管理で API キーを発行する(実キーはチャットに貼らない)。
  2. リポジトリで cd mcp/public-api → npm install && npm run build(ドキュメント Resources も使うなら mcp/api-docs も同様)。
  3. 下の env 断片と、クライアント別の mcp.json 例をコピーし、パスと YOUR_* を自分の環境に合わせる。
  4. クライアントを再起動し、Tools(list_staff など)が出ることを確認。書き込みの前に読み取りから。

どれを使うか

  • Tools MCP(public-api)

    API キー付きで /v1 を実際に呼ぶ。スタッフ一覧やスケジュール提出などをエージェントにやらせるとき。

  • Docs MCP(api-docs Resources)

    契約 markdown のみ(キー不要)。フィールド規則やリクエスト body の形が必要なとき。

  • LLM 用コピー(本ページ)

    MCP なしのチャット向けの前提テキスト。これだけでは正しい body を組み立て切れないので、MCP か下記の詳細節と併用する。

必要な環境変数(Tools MCP)

  • AUTO_SCHEDULER_PUBLIC_API_BASE_URL

    公開 REST API(/v1/*)のベース URL。サイトのドメインではなく、開通時に案内された API ホスト(末尾スラッシュ任意)

  • AUTO_SCHEDULER_API_KEY

    API 管理で発行したキー(ソース管理や公開チャットに載せない)

変数内容
AUTO_SCHEDULER_PUBLIC_API_BASE_URL公開 REST API(/v1/*)のベース URL。サイトのドメインではなく、開通時に案内された API ホスト(末尾スラッシュ任意)
AUTO_SCHEDULER_API_KEYAPI 管理で発行したキー(ソース管理や公開チャットに載せない)

環境変数の断片(コピー)

AUTO_SCHEDULER_PUBLIC_API_BASE_URL=https://api.autoschedulers.com
AUTO_SCHEDULER_API_KEY=YOUR_API_KEY

共通の準備

  1. API 管理で API キーを発行する(Tools MCP 用。ドキュメント MCP には不要)
  2. リポジトリで cd mcp/public-api → npm install && npm run build(必要なら mcp/api-docs も同様)
  3. 下のクライアント別手順で設定ファイルにエントリを追加し、パスと env を自分の環境に合わせる
  4. クライアントを再起動(または MCP を再接続)し、ツール/Resources が見えることを確認する

クライアント別の設定

設定 JSON の形はほぼ共通です。違いは設定ファイルの場所と、ChatGPT(GPT)がローカル stdio を受けない点です。

Cursor

ユーザー設定の mcp.json(例: Windows %USERPROFILE%\.cursor\mcp.json)。Cursor Settings → MCP からも編集できます。

  1. mcp.json の mcpServers に下記を追加(既存エントリは残す)
  2. 絶対パスと YOUR_BASE_URL / YOUR_API_KEY を書き換える
  3. Cursor を再起動し、Tools に list_staff などが、Resources に api-docs が出ることを確認する

Windows ではパスの \ を JSON で \\ にエスケープします。macOS / Linux は / パスで構いません。

{
  "mcpServers": {
    "auto-scheduler-public-api": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\public-api\\dist\\index.js"
      ],
      "env": {
        "AUTO_SCHEDULER_PUBLIC_API_BASE_URL": "https://api.autoschedulers.com",
        "AUTO_SCHEDULER_API_KEY": "YOUR_API_KEY"
      }
    },
    "auto-scheduler-api-docs": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\api-docs\\dist\\index.js"
      ]
    }
  }
}

public-api は Tools(キー必須)、api-docs は Resources(キー不要)です。

Claude(Desktop)

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json / Windows: %APPDATA%\Claude\claude_desktop_config.json(Settings → Developer → Edit Config)

  1. claude_desktop_config.json の mcpServers に下記を追加
  2. 絶対パスと環境変数を自分のマシンに合わせる
  3. Claude Desktop を完全終了して再起動し、Connectors / ツール一覧を確認する

Cursor と同じ mcpServers 形式です。公式の「Connect to local MCP servers」手順と同じ流れです。

{
  "mcpServers": {
    "auto-scheduler-public-api": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\public-api\\dist\\index.js"
      ],
      "env": {
        "AUTO_SCHEDULER_PUBLIC_API_BASE_URL": "https://api.autoschedulers.com",
        "AUTO_SCHEDULER_API_KEY": "YOUR_API_KEY"
      }
    },
    "auto-scheduler-api-docs": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\api-docs\\dist\\index.js"
      ]
    }
  }
}

Claude Code を使う場合はプロジェクトの .mcp.json や claude mcp add でも同様に登録できます。

Gemini(CLI)

ユーザー: ~/.gemini/settings.json / プロジェクト: .gemini/settings.json(プロジェクト側が優先)

  1. settings.json の mcpServers に下記を追加(または gemini mcp add で登録)
  2. サーバー名はハイフン区切りを推奨(Gemini CLI の制約)
  3. CLI を起動し /mcp などで接続とツール一覧を確認する

command / args / env は Cursor・Claude と同じです。必要なら timeout や trust: false を足せます。

{
  "mcpServers": {
    "auto-scheduler-public-api": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\public-api\\dist\\index.js"
      ],
      "env": {
        "AUTO_SCHEDULER_PUBLIC_API_BASE_URL": "https://api.autoschedulers.com",
        "AUTO_SCHEDULER_API_KEY": "YOUR_API_KEY"
      }
    },
    "auto-scheduler-api-docs": {
      "command": "node",
      "args": [
        "C:\\path\\to\\auto-scheduler\\mcp\\api-docs\\dist\\index.js"
      ]
    }
  }
}

Gemini のクラウドコンソール連携はリモート MCP 向けです。ローカル stdio は Gemini CLI を使ってください。

GPT(ChatGPT / OpenAI)

ChatGPT のコネクタ設定(リモート MCP)。ローカルの mcp.json はありません。

  1. ChatGPT(Web / デスクトップのコネクタ)はローカル stdio プロセスを起動できません
  2. 本製品が同梱するのはローカル stdio MCP のみのため、ChatGPT から直接は接続できません
  3. GPT から使う場合は (1) Cursor / Claude / Gemini CLI 上で同じ MCP を使う、(2) 本ページの REST(x-api-key)を Custom Actions / API から呼ぶ

リモート HTTPS MCP を自前でホストする場合のみ ChatGPT コネクタに URL を登録できます(本製品の標準提供ではありません)。

OpenAI Agents / Responses API もリモート MCP(HTTP)前提です。ローカル同梱サーバーは stdio クライアント向けです。

ツール概要(public-api)

読み取りと書き込みがあります。書き込みは課金や組織全体の設定変更につながる場合があるため、実行前に内容を確認してください。

読み取り

  • list_schedule_results / get_schedule_result(結果)
  • list_schedule_conditions(条件)
  • list_staff / get_staff(スタッフ)
  • get_schedule_defaults(スケジュール既定)
  • get_emergency_shift_context(緊急シフト context)

書き込み(確認してから)

  • submit_schedule(スケジュール実行。課金の可能性)
  • update_schedule_defaults(組織全体の既定)
  • create_staff / update_staff(スタッフ)
  • upsert_weekly_shift_wish(週次希望の全置換)
  • submit_emergency_shift(緊急シフト。有料・新条件)
  • confirm_schedule_assignments(割当確定)
  • cancel_schedule_condition(条件取消)
  • put_schedule_actual(実績の全置換)

破壊的な書き込みは実行前に内容を確認してください。ドキュメント MCP(api-docs)は Tools ではなく Resources のみです。

キーの発行: API 管理

取得 API(GET)

POST /v1/schedule と同じベース URL・同じ x-api-key です。各カードに契約のたたき台となる最小レスポンス JSON 例があります。

一覧系はクエリ limit(1〜100、既定 50)と cursor(直前の nextCursor)を受け付けます。次ページが無いとき nextCursor は省略されます。

  • GET{baseUrl}/v1/schedule-results

    スケジュール結果親行の要約一覧(新しい index 順)。

    クエリ: limit, cursor。

    レスポンス例

    {
      "items": [
        {
          "conditionId": "cond-11111111-1111-1111-1111-111111111111",
          "status": "completed",
          "candidateCount": 3,
          "createdAt": "2026-04-07T10:00:00.000Z",
          "updatedAt": "2026-04-07T10:05:00.000Z",
          "entityType": "SCHEDULE_RESULT"
        }
      ],
      "nextCursor": "eyJwayI6Ii4uLiJ9"
    }
  • GET{baseUrl}/v1/schedule-results/history

    直近+アーカイブを統合した履歴検索(ブラウザ履歴と同じ形)。

    クエリ: from, to(ISO 8601、省略時はサービス開始〜現在)、keyword、eventName(INSERT,MODIFY,REMOVE のカンマ区切り)、limit、cursor。

    レスポンス例

    {
      "items": [
        {
          "conditionId": "cond-11111111-1111-1111-1111-111111111111",
          "status": "completed",
          "candidateCount": 2,
          "createdAt": "2026-04-01T09:00:00.000Z",
          "updatedAt": "2026-04-01T09:10:00.000Z",
          "entityType": "SCHEDULE_RESULT"
        }
      ],
      "nextCursor": "eyJwayI6Ii4uLiJ9"
    }
  • GET{baseUrl}/v1/schedule-results/{conditionId}

    スケジュール結果親行を1件取得(PK/SK 除去)。

    レスポンス例

    {
      "scheduleResult": {
        "conditionId": "cond-11111111-1111-1111-1111-111111111111",
        "status": "completed",
        "candidateCount": 3,
        "entityType": "SCHEDULE_RESULT",
        "createdAt": "2026-04-07T10:00:00.000Z",
        "updatedAt": "2026-04-07T10:05:00.000Z"
      }
    }
  • GET{baseUrl}/v1/schedule-results/{conditionId}/resolution

    条件に対する解決済み最適化結果。

    status が completed で未確定のとき、この GET で rank-1 が自動確定される場合があります(副作用)。明示確定は POST …/confirm-assignments。

    レスポンス例

    {
      "resolution": {
        "status": "completed",
        "candidates": [
          {
            "rank": 1,
            "assignments": [
              {
                "personId": "550e8400-e29b-41d4-a716-446655440000",
                "personName": "Example Staff",
                "date": "2026-04-07",
                "slotId": "09:00",
                "slotLabel": "09:00"
              }
            ]
          }
        ],
        "confirmedAt": "2026-04-07T10:06:00.000Z",
        "confirmedAssignments": [
          {
            "personId": "550e8400-e29b-41d4-a716-446655440000",
            "personName": "Example Staff",
            "date": "2026-04-07",
            "slotId": "09:00",
            "slotLabel": "09:00"
          }
        ]
      }
    }
  • GET{baseUrl}/v1/schedule-results/{conditionId}/review

    手動確定用のレビューペイロード。

    レスポンス例

    {
      "review": {
        "conditionId": "cond-11111111-1111-1111-1111-111111111111",
        "status": "completed",
        "timeZone": "Asia/Tokyo",
        "calendarDates": ["2026-04-07"],
        "slotIds": ["09:00", "10:00"],
        "slotLabels": ["09:00", "10:00"],
        "requiredByCellKey": {
          "2026-04-07__09:00": 2
        },
        "candidates": [
          {
            "rank": 1,
            "assignments": [
              {
                "personId": "550e8400-e29b-41d4-a716-446655440000",
                "personName": "Example Staff",
                "date": "2026-04-07",
                "slotId": "09:00",
                "slotLabel": "09:00"
              }
            ]
          }
        ],
        "staff": [
          {
            "staffId": "550e8400-e29b-41d4-a716-446655440000",
            "displayName": "Example Staff",
            "allowedCellKeys": ["2026-04-07__09:00", "2026-04-07__10:00"]
          }
        ]
      }
    }
  • GET{baseUrl}/v1/schedule-results/{conditionId}/emergency-shift-context

    緊急シフト要求を組み立てるためのコンテキスト。有料契約が必要。

    条件が無いとき emergencyShiftContext は null。

    レスポンス例

    {
      "emergencyShiftContext": {
        "sourceConditionId": "cond-11111111-1111-1111-1111-111111111111",
        "timeZone": "Asia/Tokyo",
        "calendarDates": ["2026-04-07", "2026-04-08"],
        "staff": [
          {
            "staffId": "550e8400-e29b-41d4-a716-446655440000",
            "displayName": "Example Staff",
            "schedulingRoleIds": [],
            "availabilityByDateYmd": {}
          }
        ],
        "slots": [
          { "slotId": "09:00", "slotLabel": "09:00" }
        ],
        "dayRequirements": [],
        "roleLabelById": {},
        "rosterCandidates": []
      }
    }
  • GET{baseUrl}/v1/schedule-conditions

    スケジュール条件 index の要約一覧。

    クエリ: limit, cursor。

    レスポンス例

    {
      "items": [
        {
          "conditionId": "cond-11111111-1111-1111-1111-111111111111",
          "createdAt": "2026-04-07T10:00:00.000Z",
          "scheduleStartDate": "2026-04-07",
          "scheduleEndDate": "2026-04-13"
        }
      ],
      "nextCursor": "eyJwayI6Ii4uLiJ9"
    }
  • GET{baseUrl}/v1/schedule-conditions/{conditionId}

    条件親行+reqDays+staffSnapshots(PK/SK 除去)。

    レスポンス例

    {
      "condition": {
        "conditionId": "cond-11111111-1111-1111-1111-111111111111",
        "entityType": "SCHEDULE_CONDITION",
        "scheduleStartDate": "2026-04-07",
        "scheduleEndDate": "2026-04-13",
        "timeZone": "Asia/Tokyo"
      },
      "reqDays": [
        {
          "entityType": "SCHEDULE_CONDITION_REQ_DAY",
          "date": "2026-04-07"
        }
      ],
      "staffSnapshots": [
        {
          "entityType": "SCHEDULE_CONDITION_STAFF",
          "staffId": "550e8400-e29b-41d4-a716-446655440000",
          "displayName": "Example Staff"
        }
      ]
    }
  • GET{baseUrl}/v1/schedule-defaults

    テナントのスケジュール既定。未保存でも HTTP 200 で scheduleDefaults: null。

    レスポンス例

    {
      "scheduleDefaults": {
        "entityType": "SCHEDULE_DEFAULTS",
        "scheduleStartDate": "2026-04-07",
        "scheduleEndDate": "2026-04-13",
        "timeRangeStart": "09:00",
        "timeRangeEnd": "17:00",
        "slotGranularityMinutes": 60,
        "planningHorizon": "week",
        "requirementsByCellKey": {
          "2026-04-07__09:00": 2
        },
        "paidOptimization": {
          "laborLawCompliance": true,
          "balanceStaffLoad": false,
          "honorShiftWishes": true
        }
      }
    }
  • GET{baseUrl}/v1/schedule-actual/{conditionId}

    条件の実績割当。無ければ actual: null。

    レスポンス例

    {
      "actual": {
        "entityType": "SCHEDULE_ACTUAL",
        "conditionId": "cond-11111111-1111-1111-1111-111111111111",
        "assignments": [
          {
            "personId": "550e8400-e29b-41d4-a716-446655440000",
            "personName": "Example Staff",
            "date": "2026-04-07",
            "slotId": "09:00",
            "slotLabel": "09:00"
          }
        ]
      }
    }
  • GET{baseUrl}/v1/staff/{staffId}/weekly-shift-wish

    スタッフ1名の週次希望。無ければ weeklyShiftWish: null。論理削除スタッフは 404。

    レスポンス例

    {
      "weeklyShiftWish": {
        "entityType": "WEEKLY_SHIFT_WISH",
        "staffId": "550e8400-e29b-41d4-a716-446655440000",
        "scheduleStartDate": "2026-04-07",
        "scheduleEndDate": "2026-04-13",
        "timeRangeStart": "09:00",
        "timeRangeEnd": "11:00",
        "wishByCellKey": {
          "2026-04-07__09:00": "HIGH",
          "2026-04-07__10:00": "NONE"
        }
      }
    }
  • GET{baseUrl}/v1/staff

    テナントのアクティブスタッフ一覧(displayName 順)。

    レスポンス例

    {
      "staff": [
        {
          "staffId": "550e8400-e29b-41d4-a716-446655440000",
          "displayName": "Example Staff",
          "createdAt": "2026-03-01T00:00:00.000Z",
          "updatedAt": "2026-04-01T00:00:00.000Z",
          "laborLawCompliance": true,
          "schedulingRoleIds": [
            "550e8400-e29b-41d4-a716-446655440099"
          ]
        }
      ]
    }
  • GET{baseUrl}/v1/staff/{staffId}

    スタッフ1件(労務・Soft フィールドを含む場合あり)。論理削除は 404。

    レスポンス例

    {
      "staff": {
        "staffId": "550e8400-e29b-41d4-a716-446655440000",
        "displayName": "Example Staff",
        "createdAt": "2026-03-01T00:00:00.000Z",
        "updatedAt": "2026-04-01T00:00:00.000Z",
        "laborLawCompliance": true,
        "laborFlsaExempt": false,
        "personalMaxWeeklyMinutes": 2400,
        "laborConstraintMask": {
          "schema": "v1"
        },
        "schedulingRoleIds": [
          "550e8400-e29b-41d4-a716-446655440099"
        ],
        "preferredSchedulingRoleIds": [],
        "avoidedSchedulingRoleIds": []
      }
    }

更新 API(PATCH / POST / PUT / DELETE)

他の /v1 ルートと同じ API キーと JSON ボディです。各カードにコピー可能な最小リクエスト例があります。ユーザー(アカウント)・会社情報・監査ログは Web アプリ管轄で、この API には含めません。POST /v1/staff は契約人数上限を超えると 409(STAFF_LIMIT)を返します。

労務および Soft prefer/avoid は有料契約が必要です。例の UUID・日付・セルキーはテナントの実データに置き換えてください。

  • PATCH{baseUrl}/v1/schedule-defaults

    テナント全体のスケジュール既定を保存します。有料項目は契約プランに応じて反映されます。

    requirementsByCellKey は期間×スロットの全セルが必須(欠け・余分 → 400)。セルキーは YYYY-MM-DD__HH:mm。planningHorizon は week | two_weeks(month_attendance は拒否)。任意: requiredRolesByCellKey, laborLawJurisdiction, usLaborStateCode, linkedMonthPlanStartDate / linkedMonthPlanEndDate, laborModelVersion。

    リクエストボディ例

    {
      "scheduleStartDate": "2026-04-07",
      "scheduleEndDate": "2026-04-07",
      "timeRangeStart": "09:00",
      "timeRangeEnd": "11:00",
      "slotGranularityMinutes": 60,
      "planningHorizon": "week",
      "requirementsByCellKey": {
        "2026-04-07__09:00": 2,
        "2026-04-07__10:00": 1
      },
      "requiredRolesByCellKey": {
        "2026-04-07__09:00": {
          "550e8400-e29b-41d4-a716-446655440099": 1
        }
      },
      "paidOptimization": {
        "laborLawCompliance": true,
        "balanceStaffLoad": false,
        "honorShiftWishes": true
      }
    }
  • POST{baseUrl}/v1/staff

    スタッフを作成します。201 と staff JSON。

    受け付けるのは displayName のみです。

    リクエストボディ例

    {
      "displayName": "Example Staff"
    }
  • POST{baseUrl}/v1/schedule-results/{conditionId}/emergency-shift

    完了済み参照シフトを複製し欠勤を反映した新 condition を作成します。201 と conditionId。有料契約が必要。

    欠勤は absentDayPairs を推奨。互換: absentStaffIds + absentDatesYmd(直積)。absentSlots も可。任意で substituteDayPairs / substituteSlots(参照シフト完了済みが前提)。

    リクエストボディ例

    {
      "absentDayPairs": [
        {
          "staffId": "550e8400-e29b-41d4-a716-446655440000",
          "dateYmd": "2026-04-08"
        }
      ],
      "substituteDayPairs": [
        {
          "staffId": "660e8400-e29b-41d4-a716-446655440001",
          "dateYmd": "2026-04-08"
        }
      ]
    }
  • POST{baseUrl}/v1/schedule-results/{conditionId}/confirm-assignments

    手動編集した割当を検証して保存します。200 と { ok: true }。

    assignments は必須。relaxAvailability は任意(boolean)。

    リクエストボディ例

    {
      "assignments": [
        {
          "personId": "550e8400-e29b-41d4-a716-446655440000",
          "personName": "Example Staff",
          "date": "2026-04-07",
          "slotId": "09:00",
          "slotLabel": "09:00"
        }
      ],
      "relaxAvailability": false
    }
  • PATCH{baseUrl}/v1/staff/{staffId}

    1 名のスタッフを更新します。例のフィールドを任意組み合わせで送れます。

    個人上限は整数または null でクリア。laborConstraintMask は laborLawCompliance が true のときのみ。schedulingRoleIds / Soft prefer-avoid は UUID 配列(カタログ外はフィルタ、prefer と avoid は重複不可)。労務と Soft は有料。

    リクエストボディ例

    {
      "displayName": "Example Staff",
      "laborLawCompliance": true,
      "laborFlsaExempt": false,
      "personalMaxWeeklyMinutes": 2400,
      "personalMaxMonthlyMinutes": null,
      "personalMaxThreeMonthMinutes": null,
      "laborConstraintMask": {
        "schema": "v1"
      },
      "schedulingRoleIds": [
        "550e8400-e29b-41d4-a716-446655440099"
      ],
      "preferredSchedulingRoleIds": [
        "550e8400-e29b-41d4-a716-446655440099"
      ],
      "avoidedSchedulingRoleIds": []
    }
  • DELETE{baseUrl}/v1/staff/{staffId}

    スタッフを論理削除します(deletedAt を設定)。

    リクエストボディなし。

  • DELETE{baseUrl}/v1/schedule-conditions/{conditionId}

    条件を取り消し(publicApiCancelledAt)。子行は削除しません。

    リクエストボディなし。

  • PUT{baseUrl}/v1/schedule-actual/{conditionId}

    実績割当を保存します(条件グリッドに対して検証)。

    割当オブジェクトの形は confirm-assignments と同じです。

    リクエストボディ例

    {
      "assignments": [
        {
          "personId": "550e8400-e29b-41d4-a716-446655440000",
          "personName": "Example Staff",
          "date": "2026-04-07",
          "slotId": "09:00",
          "slotLabel": "09:00"
        }
      ]
    }
  • PUT{baseUrl}/v1/staff/{staffId}/weekly-shift-wish

    スタッフ 1 名の週次希望を全置換します。

    日付・時間帯はテナントの週次希望ナビ期間(スケジュール既定)と一致させる必要があります。wishByCellKey はその期間の全セル必須。値: NONE | LOW | HIGH。

    リクエストボディ例

    {
      "scheduleStartDate": "2026-04-07",
      "scheduleEndDate": "2026-04-13",
      "timeRangeStart": "09:00",
      "timeRangeEnd": "11:00",
      "wishByCellKey": {
        "2026-04-07__09:00": "HIGH",
        "2026-04-07__10:00": "NONE",
        "2026-04-08__09:00": "LOW",
        "2026-04-08__10:00": "NONE"
      }
    }

完了通知 Webhook

最適化(スケジュール結果)が終端状態になったとき、登録した HTTPS URL へ署名付き JSON を POST します。結果本文は含めません。詳細は公開 API(GET /v1/schedule-results/{conditionId})で取得してください。

プレイグラウンドの結果は対象外です。通知が無効、または URL 未設定のときは送信しません。

設定手順

  • サインイン後、API 管理で HTTPS の通知先 URL を保存する。
  • 「通知を有効にする」をオンにする。
  • 表示された署名シークレットを控える(再表示不可。紛失時は再生成)。
  • 受信側で署名を検証し、必要なら links.result を API キー付きで GET する。

イベント

送信される type とタイミングです。

  • schedule.result.terminal

    スケジュール結果が completed / no_solution / failed / error / canceled などに更新されたとき

typeタイミング
schedule.result.terminalスケジュール結果が completed / no_solution / failed / error / canceled などに更新されたとき

リクエストボディ

status は終端値のみ。customerId はボディに含めません。

{
  "type": "schedule.result.terminal",
  "conditionId": "019ee481-e855-7000-abd8-977cbfd64ffc",
  "status": "completed",
  "occurredAt": "2026-07-16T13:00:54.694Z",
  "links": {
    "result": "{baseUrl}/v1/schedule-results/019ee481-e855-7000-abd8-977cbfd64ffc"
  }
}

リクエストヘッダ

  • Content-Type

    application/json

  • User-Agent

    AutoScheduler-Webhook/1.0

  • X-AutoScheduler-Timestamp

    Unix 秒(文字列)

  • X-AutoScheduler-Signature

    v1=<hex>(下記の署名)

ヘッダ説明
Content-Typeapplication/json
User-AgentAutoScheduler-Webhook/1.0
X-AutoScheduler-TimestampUnix 秒(文字列)
X-AutoScheduler-Signaturev1=<hex>(下記の署名)

署名検証

受信した生ボディ(パース前)と Timestamp からダイジェストを計算し、Signature と比較します。|現在時刻 − timestamp| が 300 秒(5 分)を超えるリクエストは拒否してください(より広いずれが必要な場合を除く)。

HMAC-SHA256(signingSecret, `${timestamp}.${rawBody}`) → hex。ヘッダ値は v1=<hex>

リトライ

5xx やタイムアウト時は自動で再送します。繰り返し失敗すると配信は停止し、運用側のデッドレターに残ります。ブラウザ向けの完了通知とは別経路です。

登録・有効化: API 管理

ヘッダ

  • x-api-key

    有料契約に紐づく API キー(テナントと利用上限の識別に使用)。

  • Content-Type

    application/json

ヘッダ説明
x-api-key有料契約に紐づく API キー(テナントと利用上限の識別に使用)。
Content-Typeapplication/json

応答ヘッダについて

リクエスト ID など、一部の応答ヘッダはトレース用のメタデータです。API キーそのものではありません。機密性の高いのは主に JSON **ボディ**(会社・ユーザー情報など)です。

有料枠の上限(エンタイトルメント)

契約プランに応じた検証上限の目安です(15 分粒度・期間・登録スタッフ数など)。

  • 課金モデル

    Stripe サブスクリプション。プロダクトの請求は料金表に従い、登録スタッフ数(席)に比例する月額になり得ます(API 呼び出し回数に応じた追加課金は行いません)。

  • maxScheduleDays

    有料 2 週間詳細予測では、1 リクエストあたり最大 14 暦日(上限固定。契約でも延長しません)。

  • maxStaffPerSchedule

    POST /v1/schedule の staff 配列は最大 500 行(PUBLIC_SCHEDULE_MAX_STAFF。リクエスト本文のインライン staffId)。

  • maxRosterStaff

    POST /v1/staff の名簿登録は現行アプリ既定で最大 30 名(STAFF_ROSTER_MAX_PAID)。超過時は 409 STAFF_LIMIT。無料契約でアクティブ名簿が 5 名超のとき POST /v1/schedule は 403 FREE_STAFF_LIMIT(名簿は残る)。スケジュール設定が未保存(configuredByUser false)または SCHEDULE_DEFAULTS が無いとき POST /v1/schedule は 409 SCHEDULE_SETTINGS_REQUIRED。

  • allowedGranularities

    [60, 15] — 15 分は有料機能。60 分(時刻単位)も利用可能。

  • maxPayloadBytes

    524288(512 KiB)、特別な上限がない限り UTF-8 バイト長で計測。

  • strictUnknownRootKeys

    true — 未知のトップレベルまたは staff 内のキーは拒否

項目有料 API(目安)
課金モデルStripe サブスクリプション。プロダクトの請求は料金表に従い、登録スタッフ数(席)に比例する月額になり得ます(API 呼び出し回数に応じた追加課金は行いません)。
maxScheduleDays有料 2 週間詳細予測では、1 リクエストあたり最大 14 暦日(上限固定。契約でも延長しません)。
maxStaffPerSchedulePOST /v1/schedule の staff 配列は最大 500 行(PUBLIC_SCHEDULE_MAX_STAFF。リクエスト本文のインライン staffId)。
maxRosterStaffPOST /v1/staff の名簿登録は現行アプリ既定で最大 30 名(STAFF_ROSTER_MAX_PAID)。超過時は 409 STAFF_LIMIT。無料契約でアクティブ名簿が 5 名超のとき POST /v1/schedule は 403 FREE_STAFF_LIMIT(名簿は残る)。スケジュール設定が未保存(configuredByUser false)または SCHEDULE_DEFAULTS が無いとき POST /v1/schedule は 409 SCHEDULE_SETTINGS_REQUIRED。
allowedGranularities[60, 15] — 15 分は有料機能。60 分(時刻単位)も利用可能。
maxPayloadBytes524288(512 KiB)、特別な上限がない限り UTF-8 バイト長で計測。
strictUnknownRootKeystrue — 未知のトップレベルまたは staff 内のキーは拒否

セルごとの必要人数は 0 以上 15 以下の整数です。リクエスト頻度の上限を超えた場合はエラーが返ることがあります。

ルートで許可されるキー(厳格モード)

厳格モードでは次のトップレベルキーのみ受理されます。それ以外は UNKNOWN_FIELD になります。

  • apiVersion
  • timeZone
  • scheduleStartDate
  • scheduleEndDate
  • timeRangeStart
  • timeRangeEnd
  • slotGranularityMinutes
  • requirementsByCell
  • requiredRolesByCell(2026-09-09+)
  • paidOptimization(2026-09-13+)
  • preferredSchedulingRoleIds / avoidedSchedulingRoleIds(2026-09-14 staff)
  • staff

リクエストボディ(概要)

有料向けの公開スケジュール投入モデルに従います。暦日・タイムゾーン・スロット列(有料 API では 60 分または 15 分)・セルごとの必要人数・スタッフの可否を含みます。労働法管轄は JSON に含めません。paidOptimization は apiVersion 2026-09-13+ で任意(省略時はテナント既定)。Soft prefer/avoid のスタッフフィールドは 2026-09-14 が必要。詳細は「労働法・有料フラグ(サーバー既定)」を参照。DynamoDB キーや内部エンティティ型は本文に含めないでください。

  • apiVersion — 任意。省略または "2026-04-01" はレガシー。"2026-09-09" = 役割、"2026-09-13" = 役割 + paidOptimization、"2026-09-14" = Soft prefer/avoid。最新は 2026-09-14。
  • cellKey の形式 — requirementsByCell と availableCells のキーは、対象期間の日付と、時刻範囲・粒度から列挙された slotId を使った `${date}__${slotId}` と一致している必要があります(playground の `cellKey` と同じ規約)。

クイックリファレンス表

  • timeZone

    型
    string
    必須
    はい

    日付・スロット解釈に使う IANA タイムゾーン。

  • scheduleStartDate / scheduleEndDate

    型
    string (YYYY-MM-DD)
    必須
    はい

    対象期間(暦日)。開始 ≤ 終了。

  • timeRangeStart / timeRangeEnd

    型
    string (HH:mm)
    必須
    はい

    スロット列を定義する壁時計の範囲。1 本以上のスロットが生成されること。

  • slotGranularityMinutes

    型
    60 | 15
    必須
    はい

    有料 API: 60(時単位)または 15(15 分)。allowedGranularities に含まれること。

  • requirementsByCell

    型
    object
    必須
    はい

    キーは計算されたグリッド上の cellKey。値は 0〜15 の整数。

  • requiredRolesByCell

    型
    object
    必須
    任意 — 2026-09-09 のみ

    cellKey → roleId→need。各セルの合計 need ≤ requirementsByCell。旧版では UNKNOWN_FIELD。

  • staff

    型
    array
    必須
    はい

    空でない配列。上限は limits 参照。各要素: staffId, displayName, 任意の availableCells / laborConstraintMask / schedulingRoleIds(2026-09-09+)/ Soft prefer-avoid(2026-09-14)。

フィールド型必須備考
timeZonestringはい日付・スロット解釈に使う IANA タイムゾーン。
scheduleStartDate / scheduleEndDatestring (YYYY-MM-DD)はい対象期間(暦日)。開始 ≤ 終了。
timeRangeStart / timeRangeEndstring (HH:mm)はいスロット列を定義する壁時計の範囲。1 本以上のスロットが生成されること。
slotGranularityMinutes60 | 15はい有料 API: 60(時単位)または 15(15 分)。allowedGranularities に含まれること。
requirementsByCellobjectはいキーは計算されたグリッド上の cellKey。値は 0〜15 の整数。
requiredRolesByCellobject任意 — 2026-09-09 のみcellKey → roleId→need。各セルの合計 need ≤ requirementsByCell。旧版では UNKNOWN_FIELD。
staffarrayはい空でない配列。上限は limits 参照。各要素: staffId, displayName, 任意の availableCells / laborConstraintMask / schedulingRoleIds(2026-09-09+)/ Soft prefer-avoid(2026-09-14)。

フィールドリファレンス(許容値)

以下のフィールド規則は公開 API の検証に一致します。数値は JSON の number 型で送ってください(文字列の "60" 等は型エラーになります)。検証後、サーバーがリクエストキーではない親行既定(有料オプションのコピー・労働法管轄・モデル版など)を付与することがあります。詳細は「労働法・有料フラグ(サーバー既定)」を参照。

apiVersion

string | 省略 · 必須: いいえ(任意)

許容値

  • 省略: レガシーキー集合(2026-04-01 相当)。役割フィールドは UNKNOWN_FIELD。
  • 指定する場合は "2026-04-01" / "2026-09-09" / "2026-09-13" / "2026-09-14"。最新の公開版は 2026-09-14。
  • それ以外の文字列は拒否(TYPE_ERROR)。

挙動

  • sanitizeApiVersion でサポート版と照合。
  • バージョンで許可されるトップレベルキーおよびスタッフ行キーの集合が切り替わる(役割は 2026-09-09+、paidOptimization は 2026-09-13+、Soft prefer/avoid は 2026-09-14)。

代表エラー

  • TYPE_ERROR未サポートの apiVersion。

timeZone

string · 必須: はい

許容値

  • JSON 上は 1 つの文字列。スキーマ上「許可値をすべて列挙した enum 型」としては提供していません(ゾーン数が多く、IANA の更新にも追随する必要があるため)。サーバー側で動的に妥当性を検証します。
  • 実装はコードベースの `isValidIanaTimeZone` と同じで、Luxon の `DateTime.now().setZone(zone).isValid` が true になる必要があります。
  • IANA タイムゾーンデータベースの正規の識別子を使ってください。例: `Asia/Tokyo`, `America/New_York`, `Europe/Berlin`, `UTC`。有効な集合は、デプロイ環境の Luxon が解釈できる IANA 名に依存します。
  • `EST` や `JST` などの略称だけは IANA の安定したゾーン ID ではないため、避けてください(拒否されることがあります)。
  • 一覧の参照先の例: IANA の配布物(https://www.iana.org/time-zones)や、利用言語・OS のタイムゾーン API。

挙動

  • 日付・スロットの解釈に使用します。
  • クライアント側で固定リストが必要な場合は、同じ前提(IANA の識別子)で自前の一覧を生成するのが適切で、サーバーが JSON Schema に enum を返す前提にはしないでください。

代表エラー

  • INVALID_TIME_ZONE欠落・空・無効な IANA 名。

scheduleStartDate, scheduleEndDate

string, string · 必須: はい(両方)

許容値

  • /^\d{4}-\d{2}-\d{2}$/ に一致(トリム後)。
  • 実在する暦日であり、enumerateDates で少なくとも 1 日が得られること。
  • 期間の日数が maxScheduleDays 以下であること(有料 API は 2 週間詳細予測で最大 14 暦日・固定上限)。

挙動

  • scheduleStartDate ≤ scheduleEndDate。

代表エラー

  • INVALID_DATE_RANGE形式不正・無効な日付・空の範囲など。
  • SCHEDULE_SPAN_TOO_LONGmaxScheduleDays を超える日数。

timeRangeStart, timeRangeEnd

string, string · 必須: はい(両方)

許容値

  • 空でない文字列(トリム)。UI と同じ `enumerateSlotsByGranularity` で解釈。
  • 組み合わせにより少なくとも 1 つのスロットが生成されること。

挙動

  • slotGranularityMinutes と合わせて cellKey の slotId を決定。

代表エラー

  • INVALID_TIME_RANGE欠落、またはスロット 0 本。

slotGranularityMinutes

number(JSON 数値) · 必須: はい

許容値

  • 数値として正確に 60 または 15(文字列不可)。
  • かつ allowedGranularities に含まれること。有料 API では通常 60 と 15 の両方が有効。テナントで 15 が無効な場合は INVALID_GRANULARITY。

挙動

  • 時刻範囲と合わせてスロット本数を決定。

代表エラー

  • INVALID_GRANULARITY60/15 以外、またはプラン不許可。

requirementsByCell

Record<string, number> · 必須: はい

許容値

  • プレーンな JSON オブジェクト(配列不可)。
  • 各キーは(日付×slotId)で計算したグリッド上の cellKey であること。未知キーは UNKNOWN_CELL_KEY。
  • 各値は JSON の number で整数かつ 0〜15。
  • 省略セルは 0 相当。SHORTFALL 判定では必要人数が 1 以上のセルが対象。

挙動

  • キーは sanitizeCellKey(trim)後に照合。

代表エラー

  • INVALID_REQUIREMENTSオブジェクトでない、または数値が不正。
  • UNKNOWN_CELL_KEYグリッド外のキー。

requiredRolesByCell

object | omitted · 必須: 任意 — apiVersion 2026-09-09 のみ

許容値

  • apiVersion が "2026-09-09" のときのみ受理。省略 / 2026-04-01 では UNKNOWN_FIELD。
  • プレーンな JSON オブジェクト。各キーは requirements 格子内の cellKey。
  • 値は roleId(UUID)→ 整数 need(≥ 1)のオブジェクト。
  • 各セルで sum(need) ≤ requirementsByCell[cell](省略時は 0)。
  • 投入経路は UUID 形状と合計のみ検証(カタログ突合なし)。

挙動

  • 正規化・検証する(役割 ID は UUID、need 合計 ≤ 必要人数)。
  • 日次の必要人数行の requiredRolesBySlot として永続化。

代表的なエラー

  • UNKNOWN_FIELD旧 apiVersion で送信。
  • INVALID_REQUIREMENTS形状不正・非 UUID・合計超過。
  • UNKNOWN_CELL_KEY格子外の cellKey。

staff

array · 必須: はい(空でない配列)

許容値

  • 要素数は 1〜maxStaffPerSchedule(POST /v1/schedule 既定 500。POST /v1/staff の名簿上限とは別)。
  • 各要素はプレーンオブジェクト。apiVersion ごとに許可されるキーのみ: staffId, displayName, availableCells, laborConstraintMask。schedulingRoleIds は 2026-09-09+、preferredSchedulingRoleIds / avoidedSchedulingRoleIds は 2026-09-14(厳格モード)。
  • staffId / displayName はサニタイズを通過する必要がある(サニタイズ節参照)。
  • staffId は配列内で重複不可(DUPLICATE_STAFF_ID)。

挙動

  • 並び順は保持され、可否集計に使われる。

代表エラー

  • INVALID_STAFF空配列、超過、不正オブジェクト、サニタイズ失敗など。
  • UNKNOWN_FIELD厳格モードで staff 行に未知キー。
  • DUPLICATE_STAFF_IDstaffId の重複。

staff[].availableCells

string[] | 省略 · 必須: いいえ(任意)

許容値

  • 省略: そのスタッフはグリッド上の全セルで勤務可(内部では null 扱い)。
  • 指定時: JSON 配列。各要素は空でない文字列であり、計算グリッド上の cellKey であること。
  • 空文字列の要素は INVALID_AVAILABLE_CELL。

SHORTFALL 検証

  • 必要人数が 1 以上の各セルで、そのセルに出勤可能と数えられるスタッフ数が必要人数以上であること。

代表エラー

  • INVALID_AVAILABLE_CELL未知のセルキーまたは空要素。
  • SHORTFALL_CELLS必要人数に対して勤務可能人数が不足。

staff[].schedulingRoleIds / Soft prefer-avoid

string[] | omitted · 必須: 任意 — 役割は 2026-09-09+、Soft は 2026-09-14

許容値

  • schedulingRoleIds: apiVersion 2026-09-09+ で受理。Soft preferredSchedulingRoleIds / avoidedSchedulingRoleIds: 2026-09-14 のみ。旧版 → UNKNOWN_FIELD。
  • UUID 文字列の JSON 配列。重複は除去。Soft の prefer ∩ avoid は空であること。
  • 空配列 / 省略 = 条件スナップショット上で Hard 役割枠 / Soft 希望なし。
  • 投入経路はテナントカタログでフィルタしない。PATCH /v1/staff/{staffId} はフィルタする(Soft PATCH は有料)。

挙動

  • 正規化する(UUID 文字列、重複除去)。Soft の重複 → INVALID_STAFF。
  • 非空ならスタッフ条件スナップショット行にコピー。

代表的なエラー

  • UNKNOWN_FIELD許可されない apiVersion で送信。
  • INVALID_STAFF配列でない、要素が UUID でない、または Soft prefer/avoid の重複。

労働法・有料オプション(JSON 本文には含めない)

該当なし — サーバー側で永続化 · リクエストに含める: いいえ — これらのキーは送らない

親行に保存される内容(概要)

  • 公開 API は apiVersion ごとの許可トップレベルキーとスタッフ行キーのみ受理。laborLawJurisdiction / usLaborStateCode / laborModelVersion は送らない。paidOptimization は apiVersion 2026-09-13+ で任意。Soft prefer/avoid のスタッフフィールドは 2026-09-14 が必要。
  • 投入時、サーバーは親 SCHEDULE_CONDITION に共有既定を設定する。paidOptimization は本文(apiVersion 2026-09-13+)またはテナント SCHEDULE_DEFAULTS(省略時)。無い場合は DEFAULT_PAID_OPTIMIZATION(親 laborLawCompliance は常に true)。laborLawJurisdiction / usLaborStateCode / laborModelVersion はテナント SCHEDULE_DEFAULTS を継承(無い場合 JP / GENERIC / 管轄に応じたモデル版)。
  • オプティマイザの法令近似制約は親と各スタッフの laborLawCompliance がともに真のときに限る。スタッフ側フラグは本文では送れず、サーバーが名簿(STAFF_MEMBER)を継承する(名簿に無い staffId は既定オン)。POST /v1/staff 作成も既定オン。個別オフは有料の PATCH /v1/staff/{staffId}。
  • モデルはスケジューリング用の近似であり法的助言ではない。

補足

  • スタッフごとの労務切替と Soft prefer/avoid は有料の PATCH /v1/staff/{staffId} で管理します。更新 API を参照。

不許可キーを送った場合

  • UNKNOWN_FIELD厳格モードでルートまたは staff 行の未知プロパティを拒否。

サニタイズのルール

検証の前後で適用されます。INVALID_STAFF の原因の多くはここに該当します。

staffId

  • トリム。長さ 1〜128。
  • 許容文字: /^[a-zA-Z0-9._-]+$/(スラッシュ・バックスラッシュ不可)。

displayName

  • 制御文字・ゼロ幅除去、空白の圧縮、トリム。
  • 山括弧 < > は不可。
  • 最大 128 文字。空になったら不正。

セルキー(requirements / availableCells)

  • キーは trim 後、計算されたグリッドの cellKey と完全一致する必要がある。

成功レスポンス

202 Accepted

本文が検証を通過し条件の書き込みが行われた状態。以降の最適化は非同期で継続する場合があります。本文に conditionId 等が含まれる場合があります。

エラーコード一覧

検証エラーは安定した `code` を返します。検証前に JSON パースが走ります(INVALID_JSON, PAYLOAD_TOO_LARGE)。永続化失敗は DYNAMODB_ERROR などハンドラ依存で返る場合があります。スケジュール既定の PATCH は Zod や業務ルール失敗時に HTTP 400 と SCHEDULE_DEFAULTS_SAVE_FAILED(details に内訳)を返すことがあります。

  • INVALID_JSON

    JSON として解析できない。

  • PAYLOAD_TOO_LARGE

    UTF-8 バイト長が maxPayloadBytes(既定 512 KiB)超過。

  • TYPE_ERROR

    JSON 型が不正、または未サポートの apiVersion 文字列。

  • UNKNOWN_FIELD

    厳格モード: ルートまたは staff 行に不許可のプロパティ。

  • INVALID_TIME_ZONE

    timeZone 欠落または IANA として無効。

  • INVALID_DATE_RANGE

    日付形式不正、範囲不正、列挙が空。

  • SCHEDULE_SPAN_TOO_LONG

    開始〜終了の日数が maxScheduleDays を超過。

  • INVALID_TIME_RANGE

    時刻範囲欠落、またはスロット 0 本。

  • INVALID_GRANULARITY

    60/15 以外、またはプラン不許可。

  • INVALID_REQUIREMENTS

    requirementsByCell がオブジェクトでない、または 0〜15 以外の数値。

  • UNKNOWN_CELL_KEY

    計算されたスケジュールグリッドにないキー。

  • INVALID_STAFF

    staff が空・超過・行不正・サニタイズ失敗など。

  • DUPLICATE_STAFF_ID

    staffId の重複。

  • INVALID_AVAILABLE_CELL

    availableCells の空要素または未知キー。

  • SHORTFALL_CELLS

    必要人数に対して勤務可能人数が不足。

  • DYNAMODB_ERROR

    検証後の永続化などで失敗(ハンドラ依存)。

  • SCHEDULE_DEFAULTS_SAVE_FAILED

    PATCH /v1/schedule-defaults:検証または業務ルール失敗(error.details 参照)。

  • LABOR_COMPLIANCE_REQUIRED

    PATCH /v1/staff/{staffId}:laborLawCompliance が false のとき laborConstraintMask を送信した。

コード意味
INVALID_JSONJSON として解析できない。
PAYLOAD_TOO_LARGEUTF-8 バイト長が maxPayloadBytes(既定 512 KiB)超過。
TYPE_ERRORJSON 型が不正、または未サポートの apiVersion 文字列。
UNKNOWN_FIELD厳格モード: ルートまたは staff 行に不許可のプロパティ。
INVALID_TIME_ZONEtimeZone 欠落または IANA として無効。
INVALID_DATE_RANGE日付形式不正、範囲不正、列挙が空。
SCHEDULE_SPAN_TOO_LONG開始〜終了の日数が maxScheduleDays を超過。
INVALID_TIME_RANGE時刻範囲欠落、またはスロット 0 本。
INVALID_GRANULARITY60/15 以外、またはプラン不許可。
INVALID_REQUIREMENTSrequirementsByCell がオブジェクトでない、または 0〜15 以外の数値。
UNKNOWN_CELL_KEY計算されたスケジュールグリッドにないキー。
INVALID_STAFFstaff が空・超過・行不正・サニタイズ失敗など。
DUPLICATE_STAFF_IDstaffId の重複。
INVALID_AVAILABLE_CELLavailableCells の空要素または未知キー。
SHORTFALL_CELLS必要人数に対して勤務可能人数が不足。
DYNAMODB_ERROR検証後の永続化などで失敗(ハンドラ依存)。
SCHEDULE_DEFAULTS_SAVE_FAILEDPATCH /v1/schedule-defaults:検証または業務ルール失敗(error.details 参照)。
LABOR_COMPLIANCE_REQUIREDPATCH /v1/staff/{staffId}:laborLawCompliance が false のとき laborConstraintMask を送信した。

JSON の最小例

{
  "apiVersion": "2026-04-01",
  "timeZone": "Asia/Tokyo",
  "scheduleStartDate": "2026-04-07",
  "scheduleEndDate": "2026-04-13",
  "timeRangeStart": "08:00",
  "timeRangeEnd": "20:00",
  "slotGranularityMinutes": 60,
  "requirementsByCell": {
    "2026-04-07__slot-0": 2
  },
  "staff": [
    {
      "staffId": "550e8400-e29b-41d4-a716-446655440000",
      "displayName": "Example",
      "availableCells": ["2026-04-07__slot-0"]
    }
  ]
}

このページ内. POST /v1/schedule の本文: フィールドリファレンスと簡易表。テナント既定: 更新 API → PATCH /v1/schedule-defaults。スタッフ労務 / Soft: 更新 API → PATCH /v1/staff/{staffId}。プランと席数: 料金ページ。