Rota API and webhooks

For connecting payroll, a till or another system to EstimateIt Rota. Back to Rota set-up

Tokens

A manager makes a token under Set-up, API tokens, choosing what it can do:

The token is shown once. Rota keeps only a hash of it, so a lost token can't be shown again: revoke it and make another. Send it with every call:

Authorization: Bearer rt_...

Each token can make 60 calls a minute. Every call, allowed or refused, goes in the business's activity log.

Calls

Everything is JSON. Dates are YYYY-MM-DD, times are 24-hour HH:MM, and money is in pence.

CallScopeWhat it does
GET rota-api.php?r=peoplepeople:readReturns {people: [...]}.
POST rota-api.php?r=peoplepeople:writeSend {"person": {...}} with the fields of the People form (first, last, email, ref, dob, contract, venues, skills and so on). With an id, that person is changed. Returns {ok, person, warn}.
GET rota-api.php?r=shifts&from=&to=shifts:readThe shifts as staff were last sent them, each with its person, venue, section and status (sent, offered, accepted or confirmed).
GET rota-api.php?r=hours&from=&to=hours:readAgreed shifts with paid minutes, rate and pay, and total: {minutes, pay}. Up to 93 days at a time.

Errors come back as {error, field?} with status 400 (a bad request), 401 (no token, a wrong one or a revoked one), 403 (the token hasn't that scope), 404 (no such call) or 429 (too many calls).

Webhooks

A manager adds a webhook under Set-up, Webhooks: an https:// address, and when to send. Rota posts JSON to it:

The body is {id, event, business, at, data}. Each post has these headers:

Checking the signature

The signature is the hex HMAC-SHA256 of t, a full stop and the raw body, keyed with the webhook's signing secret (shown once, when the webhook is added). Work it out yourself, compare it in constant time, and refuse a t more than 5 minutes from now, so an old post can't be sent again. In PHP:

$body = file_get_contents('php://input');
preg_match('/^t=(\d+),v1=([a-f0-9]{64})$/', $_SERVER['HTTP_X_ROTA_SIGNATURE'] ?? '', $m) || exit(http_response_code(400));
$ok = abs(time() - (int) $m[1]) <= 300 && hash_equals(hash_hmac('sha256', $m[1] . '.' . $body, $secret), $m[2]);

Retries

Answer with any 2xx status within 5 seconds. Anything else is tried again after 1, 5, 30, 120 and 720 minutes, then given up, which goes in the activity log. Redirects aren't followed.

Hours for payroll (CSV)

Under Set-up, Hours for payroll, choose the first and last day and download the CSV. Its columns: date, employee_ref, first_name, last_name, venue, section, start, end, break_minutes, paid_hours, hourly_rate, pay, status, grade, spinal_point (the last two, from 1.25.0, say which pay scale point the rate came from, and are empty for someone with their own hourly rate), then a Total row. Only shifts people agreed to are in it: sent and not still waiting for an answer.

Back to EstimateIt · Cookie settings · Accessibility · EstimateIt is an independent tool and is not affiliated with Atlassian or Jira. · Version 1.25.0