Auto Scheduler
PreiseSpielwieseAblaufBlogHäufig gestellte FragenAPI-Dokumentation
Anmelden

Auto Scheduler

Cloud-Service für Schichtplanung und -optimierung: faire, regelkonforme Dienstpläne für Ihr Team.

Nutzungsbedingungen|Datenschutzrichtlinie|Impressum

Solver (Betreiber)

Auf dieser Seite

ÜberblickGeltungsbereichAbonnement & AbrechnungAuthentifizierungFür LLM kopierenEndpunktAufruf (Quickstart)MCP (Agenten)Lese-API (GET)Schreib-API (PATCH / POST / PUT / DELETE)Abschluss-WebhooksHeaderLimits und StandardwerteErlaubte Root-KeysAnfragetext (Überblick)KurzübersichtstabelleFelderreferenz (erlaubte Werte)apiVersiontimeZonescheduleStartDate / scheduleEndDatetimeRangeStart / timeRangeEndslotGranularityMinutesrequirementsByCellrequiredRolesByCellstaffavailableCellsstaff[].schedulingRoleIds / Soft prefer-avoidArbeitsrecht und kostenpflichtige Flags (Server-Standard)BereinigungErfolgsantwortFehlercodes (vollständig)JSON-BeispielWeiterführende Links

Auto Scheduler

Kostenpflichtige API · Abonnement

API-Referenz für Entwickler

Binden Sie die produktive API zur Übermittlung von Dienstplänen per API-Schlüssel an, der an Ihr kostenpflichtiges Abonnement gebunden ist. Mandantenweite Standardzeiten speichern Sie mit PATCH /v1/schedule-defaults; Wochen-Schichtwünsche pro Mitarbeiter lesen/ersetzen Sie mit GET/PUT /v1/staff/{staffId}/weekly-shift-wish. Die Abrechnung folgt Ihrem Plan und Vertrag (keine nutzungsabhängige API-Gebühr pro Aufruf). Diese Seite beschreibt Berechtigungen, Validierungsregeln und Fehlercodes — nutzen Sie die Seitenleiste, um Felder zu finden.

Geltungsbereich dieser Dokumentation

Diese Seite beschreibt die Produkt-REST-API für externe Integrationen.

Abschluss-Webhooks fuer Planungsergebnisse sind ausgehende HTTPS-Benachrichtigungen in der API-Verwaltung (kein REST-CRUD). Siehe Completion webhooks auf dieser Seite.

Interne Browser-Routen (z. B. Zahlungs-Callbacks oder Analytics) ersetzen diese Produkt-API nicht. Externe Systeme nutzen /v1/* und Completion-Webhooks.

Abonnement-Abrechnung und Zugriff

Diese HTTP-API ist Teil des kostenpflichtigen Produkts: Der Zugriff setzt eine aktive kommerzielle Vereinbarung voraus; Schlüssel werden nach dem Onboarding für Ihre Organisation ausgestellt.

Die Abrechnung basiert auf Abonnement und Vertrag. Bei kostenpflichtigen Plänen richten sich die Gebühren typischerweise nach registrierten Mitarbeiterplätzen pro Monat (siehe Preisseite).

Playground-/Free-Tier-Limits gelten nicht für kostenpflichtige API-Schlüssel. Effektive Grenzen (Spanne, Mitarbeiterzahl, 15-Minuten-Raster) ergeben sich aus Ihren kostenpflichtigen Berechtigungen. Siehe Limits und Standardwerte auf dieser Seite.

Authentifizierung

Anfragen müssen einen gültigen API-Schlüssel enthalten, der im Rahmen Ihres kostenpflichtigen Abonnements ausgestellt wurde. Erstellung, Rotation und Widerruf erfolgen im Konto nach der Anmeldung.

Senden Sie den Schlüssel im Header x-api-key. Schlüssel sind an Ihre Organisation für Mandantenauflösung und vertragliche Zugriffsgrenzen gebunden. Operationen außerhalb der Schlüssel-Scopes liefern 403 (API_KEY_SCOPE_DENIED). Alte Schlüssel ohne scopes-Attribut erlauben weiterhin alle Operationen.

Schlüssel verwalten: API-Verwaltung

Für LLM kopieren

Fügen Sie den Block unten in einen Chat-Assistenten ein, wenn Sie diese Produkt-API ohne MCP nutzen möchten.

Er fasst Basis-URL, Authentifizierung, Hauptoperationen und Schreibhinweise zusammen. Enthält niemals einen echten API-Schlüssel.

Für echte API-Aufrufe aus einem Agenten konfigurieren Sie MCP (Agenten) statt sich nur auf diesen Text zu verlassen.

Kontext zum Einfügen

Auto Scheduler — Public API context for LLM assistants

Use this when helping a developer call the Auto Scheduler paid product REST API (/v1/*). Prefer configuring Tools MCP when available; this paste is for chat without MCP.

Base URL
- https://api.autoschedulers.com
- Paths are under /v1/*. Do not confuse this with the marketing website origin.

Authentication
- Every request needs header: x-api-key: <API_KEY>
- Never paste a real API key into chat logs or this prompt; ask the user to supply it via environment or a secret store.
- Keys are created in the product under Account → API management.
- JSON writes: Content-Type: application/json

Read endpoints
- 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

Write endpoints (confirm with the user before calling)
- POST /v1/schedule — starts a job; may incur charges; max 14 calendar days
- PATCH /v1/schedule-defaults — tenant-wide
- POST /v1/staff
- PATCH /v1/staff/{staffId}
- PUT /v1/staff/{staffId}/weekly-shift-wish — full replace
- POST /v1/schedule-results/{conditionId}/emergency-shift — paid
- POST /v1/schedule-results/{conditionId}/confirm-assignments
- DELETE /v1/schedule-conditions/{conditionId}
- PUT /v1/schedule-actual/{conditionId} — full replace

Minimal curl (read)
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"

Contract notes
- Schedule submit body needs a supported apiVersion and valid JSON fields — see api-docs Field reference or Docs MCP Resources; do not invent fields.
- planningHorizon on defaults is only week or two_weeks (month_attendance is rejected).
- Outbound completion webhooks are HMAC-signed HTTPS callbacks configured in API management (not REST CRUD).

Safety
- Write endpoints change tenant data. Confirm destructive or irreversible actions with the user before calling them.
- Prefer read/list first when exploring an unfamiliar tenant.

Endpunkt

Übermitteln Sie eine Planbedingung als JSON. Dies ist die kostenpflichtige Integrationsschnittstelle; die genaue Basis-URL wird pro Umgebung nach Freischaltung Ihres API-Zugangs mitgeteilt.

Basis-URL

Host der öffentlichen REST-API (/v1/*), nicht die Browser-Site-URL. Setzen Sie AUTO_SCHEDULER_PUBLIC_API_BASE_URL (MCP) und BASE_URL (curl) auf diesen Wert.

AUTO_SCHEDULER_PUBLIC_API_BASE_URL — Für diese Dokumentationsumgebung konfigurierte Basis-URL. Verwenden Sie denselben Wert in MCP und curl.

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

Verwenden Sie die Basis-URL, die bei der Freischaltung Ihres API-Zugangs mitgeteilt wurde oder von Ihrem Betriebsteam bereitgestellt wird.

Aufruf (Quickstart)

Ersetzen Sie BASE_URL durch die API-Basis-URL (Pfadpräfix), die Ihnen bei der Freischaltung mitgeteilt wurde.

Senden Sie Ihren API-Schlüssel im Header **x-api-key**. Ihre Organisation (Mandant) wird aus dem Schlüssel ermittelt — Sie übergeben keine separate Mandanten-ID in der Abfragezeichenkette.

Kostenpflichtige Funktionen (Arbeitsdetails, einige Planungs-Standardwerte) erfordern ein aktives kostenpflichtiges Abonnement. Wenn die Abrechnung nicht konfiguriert ist, kann **503** zurückkommen (z. B. Code **STRIPE_NOT_CONFIGURED**). Unternehmensprofil, Audit-Logs und Benutzer-(Konto-)Verwaltung erfolgen in der Web-App und sind nicht Teil der öffentlichen API.

curl-Beispiel (bash / macOS / Linux / WSL)

Windows PowerShell: Ein abschließender `\` ist **kein** Zeilenfortsetzungszeichen. Schreiben Sie eine Zeile, oder setzen Sie am Zeilenende ein Backtick (`) für die Fortsetzung.

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 (Agenten)

Sie können dieselbe Produkt-REST-API über MCP aus Agenten wie Cursor, Claude, Gemini und GPT aufrufen. Die Operationen entsprechen der /v1-Oberfläche dieser Seite.

Die mitgelieferten MCP-Server nutzen lokales stdio. Fügen Sie command / args / env in jede Client-Konfiguration ein. Erstellen Sie Schlüssel in der API-Verwaltung (niemals committen oder in öffentliche Chats einfügen).

Nur für Dokumentation braucht ein Resources-MCP keine Anmeldung oder API-Schlüssel (mcp/api-docs). Diese Seite (/{locale}/api-docs) ist auch ohne Anmeldung sichtbar; Schlüssel erstellen erfordert weiterhin Konto → API-Verwaltung.

Schnellster Weg (empfohlen)

  1. Create an API key in Account → API management (never paste the real key into chat).
  2. In the repo: cd mcp/public-api && npm install && npm run build (also mcp/api-docs if you want documentation Resources).
  3. Copy the env snippet below and the Cursor mcp.json under Client-specific setup; replace paths and YOUR_* placeholders.
  4. Restart the client and confirm Tools (list_staff, …) appear. Prefer read tools before any write.

Welche Option nutzen

  • Tools MCP (public-api)

    Live /v1 calls with your API key. Use this when the agent should actually list staff, submit schedules, etc.

  • Docs MCP (api-docs Resources)

    Contract markdown only—no API key. Use when the agent needs field rules or request-body shape.

  • Copy for LLM (this page)

    Orientation text for chat assistants without MCP. Not enough alone for correct request bodies—pair with MCP or the sections below.

Erforderliche Umgebungsvariablen (Tools MCP)

  • AUTO_SCHEDULER_PUBLIC_API_BASE_URL

    Basis-URL der öffentlichen REST-API (/v1/*)—nicht die Website-Domain. Verwenden Sie den mitgeteilten API-Host (abschließender Schrägstrich optional)

  • AUTO_SCHEDULER_API_KEY

    Schlüssel aus der API-Verwaltung (nicht committen oder öffentlich posten)

VariableBeschreibung
AUTO_SCHEDULER_PUBLIC_API_BASE_URLBasis-URL der öffentlichen REST-API (/v1/*)—nicht die Website-Domain. Verwenden Sie den mitgeteilten API-Host (abschließender Schrägstrich optional)
AUTO_SCHEDULER_API_KEYSchlüssel aus der API-Verwaltung (nicht committen oder öffentlich posten)

Umgebungsvariablen-Snippet (kopieren)

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

Gemeinsame Vorbereitung

  1. API-Schlüssel in der API-Verwaltung erstellen (nur Tools-MCP; für Docs-MCP nicht nötig)
  2. Im Repo: cd mcp/public-api → npm install && npm run build (und mcp/api-docs für Resources)
  3. Folgen Sie den client-spezifischen Schritten unten und passen Sie Pfade und env an Ihre Maschine an
  4. Client neu starten (oder MCP neu verbinden) und prüfen, ob tools / resources erscheinen

Client-spezifische Einrichtung

Die JSON-Form ist fast überall gleich. Unterschiedlich ist der Speicherort der Konfiguration—und dass ChatGPT (GPT) keine lokalen stdio-Server startet.

Cursor

Benutzer-mcp.json (z. B. Windows %USERPROFILE%\.cursor\mcp.json). Auch bearbeitbar über Cursor Settings → MCP.

  1. Fügen Sie das Snippet unten unter mcpServers hinzu (bestehende Server behalten)
  2. Ersetzen Sie absolute Pfade sowie YOUR_BASE_URL / YOUR_API_KEY
  3. Cursor neu starten und Tools wie list_staff sowie Resources von api-docs bestätigen

Unter Windows Backslashes in JSON als \\ escapen. Unter macOS / Linux Schrägstrich-Pfade verwenden.

{
  "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 stellt Tools bereit (API-Schlüssel erforderlich). api-docs stellt Resources bereit (kein Schlüssel).

Claude (Desktop)

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

  1. Fügen Sie das Snippet unten unter mcpServers in claude_desktop_config.json hinzu
  2. Absolute Pfade und env an Ihre Maschine anpassen
  3. Claude Desktop vollständig beenden und neu starten, dann Connectors / Tools prüfen

Gleiches mcpServers-Format wie Cursor. Folgen Sie Anthropics Ablauf „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"
      ]
    }
  }
}

Mit Claude Code können Sie auch über Projekt-.mcp.json oder claude mcp add registrieren.

Gemini (CLI)

Benutzer: ~/.gemini/settings.json / Projekt: .gemini/settings.json (Projekt gewinnt, wenn beide existieren)

  1. Snippet unter mcpServers hinzufügen (oder gemini mcp add verwenden)
  2. Bevorzugen Sie Server-Namen mit Bindestrichen (Einschränkung der Gemini CLI)
  3. CLI starten und mit /mcp prüfen (Verbindung + Tools)

command / args / env entsprechen Cursor und Claude. Optionale Felder: 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-Cloud-Konsolen-Connectors zielen auf Remote-MCP. Für lokales stdio Gemini CLI verwenden.

GPT (ChatGPT / OpenAI)

ChatGPT-Connector-Einstellungen (nur Remote-MCP). Es gibt kein lokales mcp.json für ChatGPT.

  1. ChatGPT (Web-/Desktop-Connectors) kann keine lokalen stdio-MCP-Prozesse starten
  2. Dieses Produkt liefert nur lokales stdio-MCP, daher kann ChatGPT nicht direkt verbinden
  3. Für GPT-Agenten: (1) dasselbe MCP in Cursor / Claude / Gemini CLI ausführen oder (2) die REST-API dieser Seite mit x-api-key über Custom Actions / Ihren API-Client aufrufen

Einen ChatGPT-Connector können Sie nur registrieren, wenn Sie selbst ein Remote-HTTPS-MCP hosten (kein Standardangebot).

OpenAI Agents / Responses API erwarten ebenfalls Remote-MCP (HTTP). Die mitgelieferten Server sind für stdio-Clients.

Tools-Übersicht (public-api)

Lese- und Schreibtools sind verfügbar. Schreibvorgänge können kostenpflichtige Jobs starten oder organisationsweite Einstellungen ändern—vor dem Aufruf bestätigen.

Lesen

  • list_schedule_results / get_schedule_result (Ergebnisse)
  • list_schedule_conditions (Bedingungen)
  • list_staff / get_staff (Personal)
  • get_schedule_defaults (Zeitplan-Standardwerte)
  • get_emergency_shift_context

Schreiben (zuerst bestätigen)

  • submit_schedule (startet einen Zeitplan-Job; kann Kosten verursachen)
  • update_schedule_defaults (organisationsweite Standardwerte)
  • create_staff / update_staff (Personal)
  • upsert_weekly_shift_wish (vollständiger Ersatz des Wochenwunsches)
  • submit_emergency_shift
  • confirm_schedule_assignments
  • cancel_schedule_condition
  • put_schedule_actual

Confirm destructive writes before calling. Docs MCP (api-docs) is Resources-only.

Schlüssel erstellen: API-Verwaltung

Lese-Endpunkte (GET)

Gleiche Basis-URL und API-Schlüssel wie POST /v1/schedule. Jede Karte zeigt eine minimale JSON-Antwort als Vertragsskizze.

Listen akzeptieren Query limit (1–100, Standard 50) und cursor (opaker Token aus nextCursor). Ohne Folgeseite wird nextCursor weggelassen.

  • GET{baseUrl}/v1/schedule-results

    Lists schedule-result parent summaries (newest index order).

    Query: limit, cursor.

    Beispiel-Antwort

    {
      "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

    History search over recent + archive data (same shape as the browser history view).

    Query: from, to (ISO 8601; default service start→now), keyword, eventName (comma-separated INSERT,MODIFY,REMOVE), limit, cursor.

    Beispiel-Antwort

    {
      "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}

    One schedule-result parent row (PK/SK stripped).

    Beispiel-Antwort

    {
      "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

    Resolved optimization output for the condition.

    If status is completed and not yet confirmed, rank-1 may be auto-confirmed on this GET (side effect). Prefer POST …/confirm-assignments for explicit confirmation.

    Beispiel-Antwort

    {
      "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 payload for manual confirmation UI / clients.

    Beispiel-Antwort

    {
      "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

    Context for building an emergency-shift request. Paid subscription required.

    When the condition is missing, emergencyShiftContext is null.

    Beispiel-Antwort

    {
      "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

    Lists schedule-condition index summaries.

    Query: limit, cursor.

    Beispiel-Antwort

    {
      "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}

    Condition parent plus reqDays and staffSnapshots (PK/SK stripped).

    Beispiel-Antwort

    {
      "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

    Tenant schedule defaults, or null when not saved yet (still HTTP 200).

    Beispiel-Antwort

    {
      "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}

    Saved actual assignments for the condition, or null if none.

    Beispiel-Antwort

    {
      "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

    Weekly wish row for one staff member, or null if none. Soft-deleted staff → 404.

    Beispiel-Antwort

    {
      "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

    Active staff members for the tenant (sorted by displayName).

    Beispiel-Antwort

    {
      "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}

    One staff member including labor / Soft fields when present. Soft-deleted → 404.

    Beispiel-Antwort

    {
      "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": []
      }
    }

Schreibende Endpunkte (PATCH / POST / PUT / DELETE)

Gleicher API-Schlüssel und JSON-Bodies wie bei anderen /v1-Routen. Jede Karte zeigt einen kopierbaren Minimal-Request-Body. Benutzerkonten, Firmenprofil und Audit-Logs bleiben in der Web-App — nicht Teil dieser API. POST /v1/staff liefert 409 STAFF_LIMIT, wenn das Roster die Mandantengrenze überschreitet.

Arbeits- und Soft-prefer/avoid-Felder erfordern ein kostenpflichtiges Abonnement. Ersetzen Sie Beispiel-UUIDs, Daten und Zellschlüssel durch Ihre Mandantendaten.

  • PATCH{baseUrl}/v1/schedule-defaults

    Saves tenant-wide schedule defaults. Paid-tier fields follow your subscription.

    requirementsByCellKey must include every cell in period × slots (missing/extra keys → 400). Cell key = YYYY-MM-DD__HH:mm. planningHorizon: week | two_weeks (month_attendance rejected). Optional: requiredRolesByCellKey, laborLawJurisdiction, usLaborStateCode, linkedMonthPlanStartDate / linkedMonthPlanEndDate, laborModelVersion.

    Beispiel-Request-Body

    {
      "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

    Creates a staff member. Returns 201 with staff JSON.

    Only displayName is accepted.

    Beispiel-Request-Body

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

    Clones a completed source schedule with absences applied. Returns 201 with new conditionId. Paid subscription required.

    Prefer absentDayPairs. Legacy: absentStaffIds + absentDatesYmd (Cartesian). You may also send absentSlots. Optional substituteDayPairs / substituteSlots open coverage (source must be completed).

    Beispiel-Request-Body

    {
      "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

    Validates and saves manually edited assignments. Returns 200 with { ok: true }.

    assignments is required. relaxAvailability is optional (boolean).

    Beispiel-Request-Body

    {
      "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}

    Updates one staff member. Send any subset of the fields in the example.

    Personal max minutes: integer or null to clear. laborConstraintMask only when laborLawCompliance is true. schedulingRoleIds / Soft prefer-avoid: UUID arrays; unknown catalog IDs filtered; prefer and avoid must be disjoint. Labor and Soft require paid.

    Beispiel-Request-Body

    {
      "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}

    Soft-deletes a staff member (sets deletedAt).

    Kein Request-Body.

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

    Marks the condition as cancelled (publicApiCancelledAt); does not delete child rows.

    Kein Request-Body.

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

    Saves actual shift assignments (validated against the condition grid).

    Same assignment object shape as confirm-assignments.

    Beispiel-Request-Body

    {
      "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

    Replaces the weekly wish grid for one staff member (full replace).

    Dates/time range must match the tenant weekly-wish navigation window from schedule defaults. wishByCellKey must cover every cell in that window. Values: NONE | LOW | HIGH.

    Beispiel-Request-Body

    {
      "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"
      }
    }

Abschluss-Webhooks

Wenn ein Zeitplanergebnis einen Endstatus erreicht, POSTen wir eine signierte JSON-Benachrichtigung an Ihre HTTPS-URL. Der Body enthält nicht das volle Ergebnis; Details mit GET /v1/schedule-results/{conditionId} abrufen.

Playground-Ergebnisse werden nicht zugestellt. Wenn der Webhook deaktiviert ist oder keine URL gespeichert ist, wird nichts gesendet.

Einrichtung

  • Nach der Anmeldung API-Verwaltung öffnen und eine HTTPS-Benachrichtigungs-URL speichern.
  • Aktivieren Sie „Benachrichtigungen aktivieren“.
  • Kopieren Sie das einmal angezeigte Signaturgeheimnis (kann nicht erneut angezeigt werden; bei Verlust neu erzeugen).
  • Signatur am Empfänger prüfen, dann bei Bedarf links.result mit API-Schlüssel per GET abrufen.

Ereignisse

Ereignistyp und Versandzeitpunkt.

  • schedule.result.terminal

    Zeitplanergebnis-Status wird completed, no_solution, failed, error oder canceled

typeWann
schedule.result.terminalZeitplanergebnis-Status wird completed, no_solution, failed, error oder canceled

Anfragetext

status ist nur terminal. customerId fehlt im Body.

{
  "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"
  }
}

Anfrage-Header

  • Content-Type

    application/json

  • User-Agent

    AutoScheduler-Webhook/1.0

  • X-AutoScheduler-Timestamp

    Unix-Sekunden als Zeichenkette

  • X-AutoScheduler-Signature

    v1=<hex> (siehe Prüfung unten)

HeaderBeschreibung
Content-Typeapplication/json
User-AgentAutoScheduler-Webhook/1.0
X-AutoScheduler-TimestampUnix-Sekunden als Zeichenkette
X-AutoScheduler-Signaturev1=<hex> (siehe Prüfung unten)

Signaturprüfung

Berechnen Sie einen Digest aus dem Roh-Body (vor dem JSON-Parse) und dem Timestamp und vergleichen Sie mit Signature. Anfragen ablehnen, wenn |now − timestamp| 300 Sekunden (5 Minuten) überschreitet, außer Sie erlauben absichtlich größere Uhrabweichung.

HMAC-SHA256(signingSecret, `${timestamp}.${rawBody}`) → hex; Header-Wert ist v1=<hex>

Wiederholungen

Bei 5xx oder Timeout wiederholen wir automatisch. Dauerhafte Fehler gehen in eine Dead-Letter-Warteschlange. Browser-Push-Benachrichtigungen nutzen einen separaten Pfad.

Registrieren und aktivieren: API-Verwaltung

Header

  • x-api-key

    API-Schlüssel für Ihr kostenpflichtiges Abonnement (identifiziert Mandant und Planlimits).

  • Content-Type

    application/json

HeaderBeschreibung
x-api-keyAPI-Schlüssel für Ihr kostenpflichtiges Abonnement (identifiziert Mandant und Planlimits).
Content-Typeapplication/json

Antwort-Header

Einige Antwort-Header (z. B. Request-IDs) sind Trace-Metadaten, nicht Ihr API-Schlüssel. Behandeln Sie JSON-**Antworttexte** vertraulich, wenn sie Firmen- oder Nutzerdaten enthalten.

Limits der kostenpflichtigen Stufe (Berechtigungen)

Typische Validierungsgrenzen für Ihren Vertrag (15-Minuten-Raster, Planungsspanne, registrierte Mitarbeiterzahl und verwandte Obergrenzen).

  • Abrechnungsmodell

    Stripe-Abonnement; Produktgebühren skalieren typischerweise mit den registrierten Mitarbeiter-Plätzen gemäß Preisseite (keine Gebühr pro API-Aufruf).

  • maxScheduleDays

    Bis zu 14 Kalendertage pro Übermittlung für die Zwei-Wochen-Detailplanung (harte Obergrenze; vertraglich nicht erweiterbar).

  • maxStaffPerSchedule

    Bis zu 500 staff-Zeilen pro POST /v1/schedule (PUBLIC_SCHEDULE_MAX_STAFF; Inline-staffId im Body).

  • maxRosterStaff

    Bis zu 30 aktive Mitarbeitende über POST /v1/staff (STAFF_ROSTER_MAX_PAID); 409 STAFF_LIMIT bei Überschreitung.

  • allowedGranularities

    [60, 15] — 15-Minuten-Slots sind kostenpflichtig; 60 Minuten werden ebenfalls unterstützt.

  • maxPayloadBytes

    524288 (512 KiB) UTF-8, sofern kein höheres Limit gewährt wurde.

  • strictUnknownRootKeys

    true — unbekannte Keys auf Root-Ebene oder in staff werden abgelehnt

EinstellungKostenpflichtige API (typisch)
AbrechnungsmodellStripe-Abonnement; Produktgebühren skalieren typischerweise mit den registrierten Mitarbeiter-Plätzen gemäß Preisseite (keine Gebühr pro API-Aufruf).
maxScheduleDaysBis zu 14 Kalendertage pro Übermittlung für die Zwei-Wochen-Detailplanung (harte Obergrenze; vertraglich nicht erweiterbar).
maxStaffPerScheduleBis zu 500 staff-Zeilen pro POST /v1/schedule (PUBLIC_SCHEDULE_MAX_STAFF; Inline-staffId im Body).
maxRosterStaffBis zu 30 aktive Mitarbeitende über POST /v1/staff (STAFF_ROSTER_MAX_PAID); 409 STAFF_LIMIT bei Überschreitung.
allowedGranularities[60, 15] — 15-Minuten-Slots sind kostenpflichtig; 60 Minuten werden ebenfalls unterstützt.
maxPayloadBytes524288 (512 KiB) UTF-8, sofern kein höheres Limit gewährt wurde.
strictUnknownRootKeystrue — unbekannte Keys auf Root-Ebene oder in staff werden abgelehnt

Der erforderliche Personalbedarf pro Zelle bleibt eine ganze Zahl von 0 bis 15. Bei Überschreitung von Ratenlimits kann eine Fehlerantwort zurückkommen.

Erlaubte Root-Keys (Strict-Modus)

Ist der Strict-Modus aktiv, werden nur die folgenden Keys auf oberster Ebene akzeptiert. Jeder andere Key liefert 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

Anfragetext (Überblick)

Der Payload folgt dem kostenpflichtigen öffentlichen Modell: Kalendertage, Zeitzone, Slot-Raster (60 oder 15 Minuten auf der kostenpflichtigen API), Bedarf pro Zelle und Mitarbeiterverfügbarkeit. Arbeitsrechts-Hoheit ist nicht im JSON. paidOptimization ist optional für apiVersion 2026-09-13+ (sonst Mandanten-Standardwerte). Soft prefer/avoid-Mitarbeiterfelder erfordern 2026-09-14. Siehe „Arbeitsrecht und kostenpflichtige Flags“. DynamoDB-Keys und interne Entitätstypen dürfen nicht im Body stehen.

  • apiVersion — Optional. Weglassen oder „2026-04-01“ = Legacy. „2026-09-09“ = Rollen; „2026-09-13“ = Rollen + paidOptimization; „2026-09-14“ = Soft prefer/avoid. Neueste Version: 2026-09-14.
  • cellKey-Format — Keys in requirementsByCell und availableCells müssen `${date}__${slotId}` entsprechen, wobei date im Planungsbereich YYYY-MM-DD ist und slotId aus den für Zeitraum und Raster ermittelten Slots stammt (wie `cellKey` in den Playground-Hilfen).

Kurzübersichtstabelle

  • timeZone

    Typ
    string
    Erforderlich
    Ja

    IANA-Zeitzone zur Interpretation von Daten und Slots.

  • scheduleStartDate / scheduleEndDate

    Typ
    string (YYYY-MM-DD)
    Erforderlich
    Ja

    Kalenderbereich inklusiv; Start ≤ Ende.

  • timeRangeStart / timeRangeEnd

    Typ
    string (HH:mm)
    Erforderlich
    Ja

    Wanduhr-Zeitraum, der die Slot-Spalte definiert; muss mindestens einen Slot ergeben.

  • slotGranularityMinutes

    Typ
    60 | 15
    Erforderlich
    Ja

    Kostenpflichtige API: 60 (stündlich) oder 15 (Viertelstunden). Muss in allowedGranularities enthalten sein.

  • requirementsByCell

    Typ
    object
    Erforderlich
    Ja

    Keys = cellKey im berechneten Raster; Werte = ganze Zahl 0–15.

  • requiredRolesByCell

    Typ
    object
    Erforderlich
    Nein — nur 2026-09-09

    cellKey → roleId→need. Summe der needs pro Zelle ≤ requirementsByCell. Legacy-Versionen → UNKNOWN_FIELD.

  • staff

    Typ
    array
    Erforderlich
    Ja

    Nicht leer; maximale Größe siehe Limits; pro Eintrag: staffId, displayName, optional availableCells / laborConstraintMask / schedulingRoleIds (2026-09-09+) / Soft prefer-avoid (2026-09-14).

FeldTypErforderlichHinweise
timeZonestringJaIANA-Zeitzone zur Interpretation von Daten und Slots.
scheduleStartDate / scheduleEndDatestring (YYYY-MM-DD)JaKalenderbereich inklusiv; Start ≤ Ende.
timeRangeStart / timeRangeEndstring (HH:mm)JaWanduhr-Zeitraum, der die Slot-Spalte definiert; muss mindestens einen Slot ergeben.
slotGranularityMinutes60 | 15JaKostenpflichtige API: 60 (stündlich) oder 15 (Viertelstunden). Muss in allowedGranularities enthalten sein.
requirementsByCellobjectJaKeys = cellKey im berechneten Raster; Werte = ganze Zahl 0–15.
requiredRolesByCellobjectNein — nur 2026-09-09cellKey → roleId→need. Summe der needs pro Zelle ≤ requirementsByCell. Legacy-Versionen → UNKNOWN_FIELD.
staffarrayJaNicht leer; maximale Größe siehe Limits; pro Eintrag: staffId, displayName, optional availableCells / laborConstraintMask / schedulingRoleIds (2026-09-09+) / Soft prefer-avoid (2026-09-14).

Felderreferenz (erlaubte Werte)

Die folgenden Feldregeln entsprechen dem öffentlichen API-Validator. JSON-Zahlen bitte als echte Zahlen senden (nicht als Strings). Nach der Validierung kann der Server übergeordnete Standardfelder speichern (kostenpflichtige Optimierung, Arbeitsrechts-Hoheit, Modellversion), die keine Request-Keys sind — siehe „Arbeitsrecht und kostenpflichtige Flags“.

apiVersion

string | ausgelassen · Erforderlich: Nein — optional

Erlaubte Werte

  • Ausgelassen: akzeptiert als Legacy-Schlüsselsatz (wie 2026-04-01). Rollenfelder → UNKNOWN_FIELD.
  • Wenn gesetzt: „2026-04-01“, „2026-09-09“, „2026-09-13“ oder „2026-09-14“. Neueste veröffentlichte Version ist 2026-09-14.
  • Jede andere Zeichenkette wird abgelehnt (TYPE_ERROR).

Verhalten

  • Vergleich nach trim-äquivalenter Verarbeitung in sanitizeApiVersion.
  • Die Version wählt die erlaubten Schlüsselmengen auf Top-Level und Staff-Objekt (Rollen ab 2026-09-09+; paidOptimization ab 2026-09-13+; Soft prefer/avoid ab 2026-09-14).

Typische Fehler

  • TYPE_ERRORNicht unterstützter apiVersion-Wert.

timeZone

string · Erforderlich: Ja

Erlaubte Werte

  • Übertragung als einzelne Zeichenkette. Die API veröffentlicht keine vollständige Enum aller erlaubten Zonen: der Server validiert dynamisch.
  • Validierung entspricht `isValidIanaTimeZone`: Luxon `DateTime.now().setZone(zone).isValid` muss true sein.
  • Verwenden Sie kanonische IANA-Bezeichner, z. B. `Asia/Tokyo`, `America/New_York`, `Europe/Berlin`, `UTC`.
  • Nur Abkürzungen wie `EST`, `JST`, `GMT` sind keine stabilen IANA-IDs und können abgelehnt werden.
  • Listen: IANA-TZ-Distribution (https://www.iana.org/time-zones) oder die Zeitzone-API Ihrer Plattform.

Verhalten

  • Wird für Daten und Slot-Zeiten in der Normalisierung verwendet.
  • Für eine feste Client-Liste dieselben Regeln (IANA-IDs) ableiten, nicht auf eine Server-Enum im JSON-Schema vertrauen.

Typische Fehler

  • INVALID_TIME_ZONEFehlt, leer oder keine gültige IANA-Zone.

scheduleStartDate, scheduleEndDate

string, string · Erforderlich: Ja — beide

Erlaubte Werte

  • Muss /^\d{4}-\d{2}-\d{2}$/ (getrimmt) entsprechen.
  • Echte Kalendertage; der inklusive Bereich muss mindestens einen Tag über enumerateDates ergeben.
  • Anzahl der Tage darf maxScheduleDays nicht überschreiten (kostenpflichtige API: harte Obergrenze 14 Tage für Zwei-Wochen-Planung).

Verhalten

  • scheduleStartDate muss vor oder am scheduleEndDate liegen.

Typische Fehler

  • INVALID_DATE_RANGEFalsches Format, ungültige Daten oder leerer Bereich.
  • SCHEDULE_SPAN_TOO_LONGMehr als maxScheduleDays Tage.

timeRangeStart, timeRangeEnd

string, string · Erforderlich: Ja — beide

Erlaubte Werte

  • Nicht leere Strings (getrimmt), gleiche Slot-Ermittlung wie in der UI (`enumerateSlotsByGranularity`).
  • Das Paar muss mindestens einen Slot erzeugen, sonst schlägt die Validierung fehl.

Verhalten

  • Definiert zusammen mit slotGranularityMinutes die slotId-Werte für cellKey.

Typische Fehler

  • INVALID_TIME_RANGEFehlende Werte oder null Slots für den Bereich.

slotGranularityMinutes

number (JSON-Zahl) · Erforderlich: Ja

Erlaubte Werte

  • Exakt 60 oder 15 (nicht als String).
  • Muss in allowedGranularities vorkommen. Bei der kostenpflichtigen API sind meist beide erlaubt; wenn 15 für den Mandanten deaktiviert ist: INVALID_GRANULARITY.

Verhalten

  • Bestimmt zusammen mit dem Zeitraum die Slot-Anzahl.

Typische Fehler

  • INVALID_GRANULARITYNicht 60/15 oder im Plan nicht erlaubt.

requirementsByCell

Record<string, number> · Erforderlich: Ja

Erlaubte Werte

  • Plain JSON-Objekt (kein Array).
  • Jeder Key muss ein cellKey im erwarteten Raster (Daten × slotIds) sein. Unbekannte Keys → UNKNOWN_CELL_KEY.
  • Jeder Wert: JSON-Zahl, ganzzahlig, 0 bis 15 inklusive.
  • Fehlende Zellen gelten als Bedarf 0 (SHORTFALL nur bei Bedarf ≥ 1).

Verhalten

  • Keys werden nach trim über sanitizeCellKey verglichen.

Typische Fehler

  • INVALID_REQUIREMENTSKein Objekt oder ungültiger Zahlenwert.
  • UNKNOWN_CELL_KEYKey nicht im berechneten Datums-Slot-Raster.

requiredRolesByCell

object | omitted · Erforderlich: Nein — optional; nur apiVersion 2026-09-09

Zulässige Werte

  • Nur akzeptiert, wenn apiVersion „2026-09-09“ ist. Weggelassen / 2026-04-01 → UNKNOWN_FIELD.
  • Muss ein einfaches JSON-Objekt sein. Jeder Schlüssel ist ein cellKey im requirements-Raster.
  • Jeder Wert ist ein Objekt roleId (UUID) → ganzzahliges need ≥ 1.
  • Für jede Zelle muss sum(need) ≤ requirementsByCell[cell] sein (oder 0 wenn weggelassen).
  • Der Submit-Pfad prüft nur UUID-Form und Summe (kein Katalog-Lookup).

Verhalten

  • Werte werden normalisiert und geprüft (UUID-Rollen-IDs; Summe der needs ≤ Kopfzahl).
  • Als requiredRolesBySlot auf täglichen Bedarfzeilen gespeichert.

Typische Fehler

  • UNKNOWN_FIELDBei Legacy-apiVersion gesendet.
  • INVALID_REQUIREMENTSFalsche Form, roleId kein UUID oder Summe überschreitet die Kopfzahl.
  • UNKNOWN_CELL_KEYcellKey nicht im berechneten Raster.

staff

array · Erforderlich: Ja — nicht leeres Array

Erlaubte Werte

  • Länge zwischen 1 und maxStaffPerSchedule (Standard 500 für POST /v1/schedule; getrennt vom Listenlimit für POST /v1/staff).
  • Jedes Element muss ein Plain-Objekt mit nur den für die apiVersion erlaubten Keys sein: staffId, displayName, availableCells, laborConstraintMask; plus schedulingRoleIds ab 2026-09-09+; plus preferredSchedulingRoleIds / avoidedSchedulingRoleIds ab 2026-09-14 (Strict-Modus).
  • staffId und displayName müssen die Bereinigung überstehen (Abschnitt Bereinigung).
  • staffId muss im Array eindeutig sein (DUPLICATE_STAFF_ID).

Verhalten

  • Reihenfolge bleibt für die Verfügbarkeitszählung erhalten.

Typische Fehler

  • INVALID_STAFFLeeres Array, zu viele Zeilen, ungültiges Objekt oder Bereinigung fehlgeschlagen.
  • UNKNOWN_FIELDZusätzlicher Key am staff-Objekt im Strict-Modus.
  • DUPLICATE_STAFF_IDDerselbe staffId zweimal.

staff[].availableCells

string[] | ausgelassen · Erforderlich: Nein — optional

Erlaubte Werte

  • Ausgelassen: Mitarbeiter gilt auf allen Zellen des Rasters als verfügbar (intern null = „alle Zellen“).
  • Wenn gesetzt: JSON-Array von Strings; jeder nicht leere String muss ein cellKey im erwarteten Raster sein.
  • Leere Strings im Array sind ungültig (INVALID_AVAILABLE_CELL).

SHORTFALL-Prüfung

  • Für jede Zelle mit Bedarf ≥ 1 muss die Anzahl verfügbarer Mitarbeiter ≥ Bedarf sein, sonst SHORTFALL_CELLS.

Typische Fehler

  • INVALID_AVAILABLE_CELLUnbekannter cellKey oder leerer Eintrag.
  • SHORTFALL_CELLSZu wenig Personal für den erforderlichen Bedarf in einer Zelle.

staff[].schedulingRoleIds / Soft prefer-avoid

string[] | omitted · Erforderlich: Nein — optional; Rollen ab 2026-09-09+; Soft ab 2026-09-14

Zulässige Werte

  • schedulingRoleIds: akzeptiert ab apiVersion 2026-09-09+. Soft preferredSchedulingRoleIds / avoidedSchedulingRoleIds: nur 2026-09-14. Ältere Versionen → UNKNOWN_FIELD.
  • JSON-Arrays aus UUID-Zeichenketten. Duplikate werden entfernt. Soft prefer ∩ avoid muss leer sein.
  • Leeres Array / weglassen = kein Hard-Rollenrahmen / keine Soft-Präferenz im Bedingungs-Snapshot.
  • Der Submit-Pfad filtert nicht gegen den Mandantenkatalog; PATCH /v1/staff/{staffId} schon (Soft-PATCH kostenpflichtig).

Verhalten

  • Werte werden normalisiert (UUID-Zeichenketten; Duplikate entfernt). Soft-Überlappung → INVALID_STAFF.
  • Bei Nichtleerheit auf Staff-Bedingungs-Snapshot-Zeilen kopiert.

Typische Fehler

  • UNKNOWN_FIELDBei einer apiVersion gesendet, die den Key nicht erlaubt.
  • INVALID_STAFFKein Array, kein UUID-Element oder Soft prefer/avoid-Überlappung.

Arbeitsrecht und kostenpflichtige Optimierung (nicht im JSON-Body)

n/v — serverseitig gespeichert · In der Anfrage: Nein — diese Keys niemals senden

Was die API in der übergeordneten Zeile speichert

  • Die öffentliche API akzeptiert nur die für Ihre apiVersion erlaubten Top-Level- und Staff-Objekt-Schlüssel. Senden Sie nicht laborLawJurisdiction, usLaborStateCode oder laborModelVersion. paidOptimization ist optional für apiVersion 2026-09-13+. Soft prefer/avoid-Mitarbeiterfelder erfordern 2026-09-14.
  • Bei Übermittlung setzt der Server die übergeordnete SCHEDULE_CONDITION aus gemeinsamen Standardwerten: paidOptimization aus dem Body (apiVersion 2026-09-13+) oder Mandanten SCHEDULE_DEFAULTS bei Auslassung; sonst DEFAULT_PAID_OPTIMIZATION (Eltern-laborLawCompliance erzwungen an). laborLawJurisdiction / usLaborStateCode / laborModelVersion werden von Mandanten SCHEDULE_DEFAULTS geerbt (Fallback JP / GENERIC / Modell zur Jurisdiktion).
  • Gesetzliche Arbeitszeitgrenzen im Optimierer erfordern sowohl übergeordnete als auch pro-Mitarbeiter-Compliance-Flags. Pro-Mitarbeiter-Flags stehen nicht im JSON: der Server übernimmt sie aus der Personalstammliste (fehlende staffIds standardmäßig an). POST /v1/staff legt ebenfalls an; Abschalten pro Person über bezahltes PATCH /v1/staff/{staffId}.
  • Das Arbeitszeitmodell ist eine Näherung für die Planung, keine Rechtsberatung. Katalog: .

Dokumentation

  • Ausführlich: this page und §3.1.

Bei unzulässigen Keys

  • UNKNOWN_FIELDStrict-Modus lehnt unbekannte Root- oder staff-Eigenschaften ab.

Regeln zur Bereinigung

Wird vor oder während der Validierung angewendet. Diese Regeln erklären, warum ein Wert als INVALID_STAFF abgelehnt werden kann.

staffId

  • Trim; Länge 1–128.
  • Zeichen müssen /^[a-zA-Z0-9._-]+$/ entsprechen (keine Schrägstriche oder Backslashes).

displayName

  • Steuerzeichen und Zero-Width entfernen; Leerzeichen zusammenführen; trim.
  • Winkelklammern < und > sind nicht erlaubt.
  • Max. 128 Zeichen nach Bereinigung; darf nicht leer werden.

Zell-Keys (requirements / availableCells)

  • Keys werden getrimmt; müssen exakt den cellKey-Strings im berechneten Raster entsprechen.

Erfolgsantwort

202 Accepted

Der Anfragetext hat die Validierung bestanden und die Bedingung wurde geschrieben; die Optimierung kann asynchron weiterlaufen. Der Handler kann einen JSON-Body mit conditionId usw. zurückgeben.

Fehlercodes (vollständig)

Validierungsfehler liefern strukturierte Informationen mit stabilem `code`. Parsen vor der Validierung (INVALID_JSON, PAYLOAD_TOO_LARGE). Persistenzfehler können als DYNAMODB_ERROR erscheinen. PATCH /v1/schedule-defaults kann SCHEDULE_DEFAULTS_SAVE_FAILED (HTTP 400) mit Details liefern.

  • INVALID_JSON

    Body ist kein gültiges JSON.

  • PAYLOAD_TOO_LARGE

    UTF-8-Byte-Länge überschreitet maxPayloadBytes (Standard 512 KiB).

  • TYPE_ERROR

    Falscher JSON-Typ oder nicht unterstützte apiVersion-Zeichenkette.

  • UNKNOWN_FIELD

    Strict-Modus: nicht erlaubte Eigenschaft auf Root oder staff-Objekt.

  • INVALID_TIME_ZONE

    timeZone fehlt oder ist kein gültiger IANA-Name.

  • INVALID_DATE_RANGE

    Daten nicht YYYY-MM-DD, ungültiger Bereich oder leere Aufzählung.

  • SCHEDULE_SPAN_TOO_LONG

    Zu viele Tage zwischen Start und Ende (siehe maxScheduleDays).

  • INVALID_TIME_RANGE

    Zeitraum fehlt oder ergibt null Slots.

  • INVALID_GRANULARITY

    slotGranularityMinutes nicht 60/15 oder im Plan nicht erlaubt.

  • INVALID_REQUIREMENTS

    requirementsByCell kein Objekt oder Zahl nicht 0–15.

  • UNKNOWN_CELL_KEY

    Key nicht im berechneten Planungsraster.

  • INVALID_STAFF

    staff leer, zu groß, ungültige Zeile oder Bereinigung fehlgeschlagen.

  • DUPLICATE_STAFF_ID

    Doppelte staffId-Werte.

  • INVALID_AVAILABLE_CELL

    Leerer oder unbekannter Eintrag in availableCells.

  • SHORTFALL_CELLS

    Unzureichende Verfügbarkeit gegenüber dem Bedarf.

  • DYNAMODB_ERROR

    Vorübergehender oder Persistenzfehler nach der Validierung (handlerabhängig).

  • SCHEDULE_DEFAULTS_SAVE_FAILED

    PATCH /v1/schedule-defaults: Validierung oder Geschäftsregeln fehlgeschlagen (siehe error.details).

  • LABOR_COMPLIANCE_REQUIRED

    PATCH /v1/staff/{staffId}: laborConstraintMask gesendet, obwohl laborLawCompliance false ist.

CodeBedeutung
INVALID_JSONBody ist kein gültiges JSON.
PAYLOAD_TOO_LARGEUTF-8-Byte-Länge überschreitet maxPayloadBytes (Standard 512 KiB).
TYPE_ERRORFalscher JSON-Typ oder nicht unterstützte apiVersion-Zeichenkette.
UNKNOWN_FIELDStrict-Modus: nicht erlaubte Eigenschaft auf Root oder staff-Objekt.
INVALID_TIME_ZONEtimeZone fehlt oder ist kein gültiger IANA-Name.
INVALID_DATE_RANGEDaten nicht YYYY-MM-DD, ungültiger Bereich oder leere Aufzählung.
SCHEDULE_SPAN_TOO_LONGZu viele Tage zwischen Start und Ende (siehe maxScheduleDays).
INVALID_TIME_RANGEZeitraum fehlt oder ergibt null Slots.
INVALID_GRANULARITYslotGranularityMinutes nicht 60/15 oder im Plan nicht erlaubt.
INVALID_REQUIREMENTSrequirementsByCell kein Objekt oder Zahl nicht 0–15.
UNKNOWN_CELL_KEYKey nicht im berechneten Planungsraster.
INVALID_STAFFstaff leer, zu groß, ungültige Zeile oder Bereinigung fehlgeschlagen.
DUPLICATE_STAFF_IDDoppelte staffId-Werte.
INVALID_AVAILABLE_CELLLeerer oder unbekannter Eintrag in availableCells.
SHORTFALL_CELLSUnzureichende Verfügbarkeit gegenüber dem Bedarf.
DYNAMODB_ERRORVorübergehender oder Persistenzfehler nach der Validierung (handlerabhängig).
SCHEDULE_DEFAULTS_SAVE_FAILEDPATCH /v1/schedule-defaults: Validierung oder Geschäftsregeln fehlgeschlagen (siehe error.details).
LABOR_COMPLIANCE_REQUIREDPATCH /v1/staff/{staffId}: laborConstraintMask gesendet, obwohl laborLawCompliance false ist.

Minimales JSON-Beispiel

{
  "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"]
    }
  ]
}

Auf dieser Seite. POST /v1/schedule: Feldreferenz und Kurztabelle. Mandanten-Standardwerte: Schreibende Endpunkte → PATCH /v1/schedule-defaults. Personal Arbeit / Soft: PATCH /v1/staff/{staffId}. Pläne: Preisseite.