ShiftLine

REST API

Create a key in Admin → Integrations and send it as Authorization: Bearer sl_…. All responses are JSON unless a file format is requested.

GET /api/v1/bids?status=published

List bids (filter by status).

GET /api/v1/bids/{id}

A bid with lines, shifts, results and violations.

GET /api/v1/bids/{id}/export?format=csv|xlsx|custom&formatId=…

Bid package in a file format or a tenant-configured bidding-system format.

GET /api/v1/workgroups

Stations + workgroups with their contracts.

GET /api/v1/rules?workgroupId=…&date=YYYY-MM-DD

Effective resolved rules with sources and conflicts.

POST /api/v1/curves

Push a demand curve version: { workgroupId, intervalMinutes, mode, label, days: [{ key: 'mon', values: [...] }] }.

Webhooks

Events: bid.submitted, bid.approved, bid.rejected, bid.published, rule.approved. Each POST carries x-shiftline-event and x-shiftline-signature: t=<unix>,v1=<hex>, where v1 = HMAC_SHA256(secret, `${t}.${body}`).

import crypto from "node:crypto"
const [t, v1] = sig.split(",").map((p) => p.split("=")[1])
const ok = crypto.timingSafeEqual(
  Buffer.from(v1),
  Buffer.from(crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex")),
)