All API requests must be authenticated using Bearer tokens. Include your token in the Authorization header of every request.
Retrieving a token
Contact your Plan My Shifts administrator to obtain your authentication token. Tokens are department-specific and grant access only to your organization's scheduling data.
Using your token
Include the token in the Authorization header with the Bearer prefix:
curl -H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-X POST https://prod-scheduler.datapult.dk/api/v1/gateway \
--data-binary @schedule.json
Gateway submissions are accepted on /api/v1/gateway. Put your solved-schedule receiver in the request's callbackUrl; the solver calls that URL when the job completes.
The submission response is the public request identifier. GET /api/v1/gateway returns it as solverProblemId, and DELETE /api/v1/gateway/{solverProblemId} accepts the same string. This compatibility identifier currently matches the numeric gateway row ID but remains a string API contract.
The gateway is served by the scheduler application. The Laravel application does not expose gateway or token-creation endpoints.
Authentication responses
The API returns standard HTTP status codes for authentication:
- 200 / 201 - Request authenticated and processed
- 401 Unauthorized - Missing or invalid token
- 403 Forbidden - Token valid but lacks permission for this resource
Always check response status codes in your integration to handle authentication failures gracefully.
Solver runs and callbacks
POST /solver/solve accepts a gzipped multipart schedule part containing a solve envelope with runId, problem, and callback. The caller owns the run ID and all durable state. The solver keeps only active jobs in memory.
The callback receives ordered events for the same run:
bestcontains a throttled intermediate assignment snapshot.completedcontains the final solution.failedcontains terminal failure information when solving cannot complete.
Laravel supplies a two-hour relative signed callback URL. The solver sends no Laravel bearer token; the signature in the callback URL authenticates the event even when the externally reachable callback host differs from Laravel's canonical APP_URL.
Every event includes type, runId, and a positive sequence. Consumers must reject stale run IDs and process best events idempotently by sequence. Terminal delivery is retried; the caller should also mark an overdue pending run failed if no terminal event arrives.
POST /solver/{runId}/terminate stops an active run. Completed and failed runs are not retained by the solver.
Fixed schedule evaluation
First-party clients can evaluate existing assignments without starting an optimizer job with POST /solver/evaluate-fixed-schedule. The request uses the same gzipped multipart schedule payload as /solver/evaluate-denested.
The endpoint validates and initializes the submitted schedule, runs score explanation for the fixed assignments, and returns:
constraintReleasefreePeriodSelectionsresidualFreeDaysunresolvedFreePeriodRequirements
It does not create a solver problem, change shift assignments, require callback configuration, or call the optimizer solve loop.