Developers
The HelloMapper API
Sync approved timesheets to payroll, push shifts from another system, and hear about changes the moment they happen. Included in Workforce Growth and Scale.
OpenAPI 3.1: https://api.hellomapper.com/public/v1/openapi.json · v1.0.0
1. Create an API client
In HelloMapper, an owner or admin goes to Settings → Integrations & API and creates a client for each system that connects, choosing what it may do. The client secret is shown once.
2. Get an access token
OAuth 2.0 client credentials. Tokens last an hour; request a new one when it expires.
curl -u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=client_credentials \
https://api.hellomapper.com/oauth/token
{"access_token":"hmat_…","token_type":"Bearer","expires_in":3600,"scope":"shifts:read timesheets:read"}3. Call the API
curl -H "Authorization: Bearer $TOKEN" \ "https://api.hellomapper.com/public/v1/timesheets?from=2026-10-01T00:00:00Z&to=2026-10-15T00:00:00Z"
| Endpoint | What it does | Scope |
|---|---|---|
| GET/incidents | Incidents, newest first | incidents:read |
| GET/incidents/{id} | Get an incident | incidents:read |
| GET/people | The organisation's people (staff and workers) | people:read |
| GET/shifts | List shifts starting in a window (max 62 days) | shifts:read |
| POST/shifts | Create a shift (assignments go through the usual clash, leave and eligibility checks) | shifts:write |
| GET/shifts/{id} | Get a shift | shifts:read |
| GET/timesheets | Timesheet lines checked in within a window, approved only by default (for payroll) | timesheets:read |
Limits: 600 requests a minute per client. Errors are JSON {"error": {"code", "message"}}; validation failures list fields.
4. Webhooks
Register an https endpoint for any of these events. Each delivery is a small JSON envelope; fetch the object through the API. Anything other than a 2xx is retried with backoff for about 12 hours.
incident.reportedshift.assignedshift.cancelledshift.claimedshift.createdshift.unassignedtimesheet.approved
POST /your/endpoint
HelloMapper-Signature: t=1791000000,v1=5f1c…
HelloMapper-Event: shift.created
{"id":"evt_…","type":"shift.created","created_at":"2026-10-02T09:00:00Z",
"data":{"object":"shift","id":"8ec7c51c-…"}}Verify the signature with the endpoint's signing secret before trusting a delivery:
import crypto from "node:crypto";
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}