The partner API lets software you already run, payroll, scheduling, reporting, read one FlowState store: its people, published shifts, availability, time records and payroll. It is read-only today. Every token is scoped to one store and to the categories of data an owner ticked when creating it, and every request made with a token is written to that store's security log.
Getting access
- FlowState switches the partner API on per store. It is off by default. Email support@flowstateqsr.com with the store number; it is turned on the same business day.
- An owner creates a token in the app, in the tools list under Manage, Partner API (or type "API" into the red search button): a name for the software that will use it, and the scopes it may read. The full token is shown once, at creation. Only the prefix and the last four characters are ever shown again.
- Revoke from the same screen. Revocation is immediate. Creating and revoking a token are both recorded in the store's security log with the owner's name.
Authentication
Send the token as a bearer credential on every request:
`` Authorization: Bearer fs_live_<store>.<secret> ``
The store number is in the prefix; the secret is 64 hexadecimal characters and is stored hashed on our side, so it cannot be recovered from us. Session cookies and the apps' own device tokens are refused on /api/v1 paths.
An unknown or revoked token answers 401. Repeated failed authentications from one network address answer 429 with a Retry-After of sixty seconds.
Scopes
A token carries one or more of these. A request whose endpoint needs a scope the token does not carry answers 403 with code: "scope_not_granted". A token created with no scopes gets members:read.
| Scope | What it unlocks |
|---|---|
members:read |
GET /api/v1/members and GET /api/v1/members/:id: id, name, username, role, nickname, avatar, active flag |
contacts:read |
email and phone on each member |
birthdays:read |
birthday on each member, as MM-DD, never the year |
labor:read |
dob on each member, as YYYY-MM-DD, for under-18 labor rules |
availability:read |
GET /api/v1/availability |
shifts:read |
GET /api/v1/shifts |
punches:read |
GET /api/v1/punches |
payroll:read |
GET /api/v1/payroll.csv, and wage on each member where an owner entered an hourly wage |
Wages entered by the person themselves are never exposed; only a wage an owner or leader set appears, and only with payroll:read.
Response envelope
Every JSON response has the same shape:
`` { "ok": true, "store": "05348", "data": [ ... ], "next_cursor": null } ``
Single-record endpoints put the object in data instead of an array. Errors answer { "ok": false, "error": "...", "code": "...", "ref": "..." }; quote ref when you write to us about a request.
Pagination
List endpoints take limit (1 to 200, default 50) and cursor. Rows are ordered by id ascending. When more rows remain, next_cursor carries the id of the last row returned; pass it back as cursor to continue. When it is null, you have everything.
Rate limits
60 requests per minute and 10,000 per day, per token. Over either limit the response is 429 with a Retry-After header in seconds.
Errors
| Status | Meaning |
|---|---|
400 |
A bad date range, for example an end before the start or a payroll span over 62 days |
401 |
Unknown or revoked token, or no token |
402 |
The store's subscription has ended or was refunded (code: "store_locked"); access resumes when it is restored |
403 |
The token lacks the scope (code: "scope_not_granted"), or the store has not turned on the feature the endpoint reads |
404 |
No such record in this store |
429 |
Rate limited; wait for Retry-After |
Endpoints
Dates are YYYY-MM-DD in the store's own time zone. Times of day are HH:MM on a 24-hour clock, and *_mins values are minutes from midnight.
GET /api/v1/members
Scope members:read. Everyone who works at the store, excluding deleted people and FlowState's own administrative account. Each member:
| Field | Notes |
|---|---|
id |
Stable numeric id, the same one shifts and punches reference as user_id |
name, username, role |
Role is one of team_member, shift_leader, kitchen_director, marketing_director, owner |
nickname |
Or null |
avatar |
A path on flowstateqsr.com, or null |
active |
true for everyone this endpoint returns |
trainer |
Present and true for certified trainers |
email, phone |
With contacts:read; null when not entered |
birthday |
With birthdays:read, as MM-DD |
dob |
With labor:read, as YYYY-MM-DD |
wage |
With payroll:read, a number, only when an owner entered it |
GET /api/v1/members/:id
Scope members:read. One member, same fields. 404 for an unknown, deleted or administrative id.
GET /api/v1/shifts
Scope shifts:read. Published shifts only; a draft week is not visible until the leader posts it. Filters: from and to, inclusive dates. Each shift:
| Field | Notes |
|---|---|
id, user_id, date |
|
start, end |
HH:MM |
start_mins, end_mins |
Minutes from midnight on date. A shift that ends after midnight has an end_mins above 1440 |
position, station |
The store's own names; empty strings when not set |
published |
Always true here |
POST /api/v1/shifts
Reserved. Answers 403 with code: "scope_not_granted" for every token today. Writing shifts from outside is planned; tell us what you would send and in what shape.
GET /api/v1/availability
Scope availability:read. One row per active person, paged by the person's id. Optional user_id returns one person. Each row:
| Field | Notes |
|---|---|
id, user_id |
Both the person's id |
weekly |
An object keyed "0" (Sunday) to "6" (Saturday); each value is a list of { "start": "HH:MM", "end": "HH:MM" } windows the person can work. A window whose end is before its start runs past midnight |
blackouts |
Dates the person is unavailable, including approved time off, sorted |
note |
Free text the person wrote, or an empty string |
upcoming |
An approved change that has not started yet, as { "effective_from": "YYYY-MM-DD", "weekly": { ... } }, or null. From that date the person's weekly becomes this one |
GET /api/v1/punches
Scope punches:read. Requires the store to run its timeclock in FlowState; otherwise 403 with a message saying which timekeeping mode the store is in. Filters: from and to. Each punch:
| Field | Notes |
|---|---|
id, user_id, date |
date is the store day the punch belongs to |
in_at, out_at |
ISO 8601 timestamps; out_at is null while the person is still clocked in |
scheduled |
Whether the punch matched a scheduled shift |
GET /api/v1/payroll.csv
Scope payroll:read. Requires the timeclock. Parameters from and to (start and end are accepted as aliases); the default range is the current week, Monday through today; the maximum span is 62 days. The response is text/csv with a Content-Disposition filename and the header X-CSV-Version: 2. Columns, in order:
`` Date, Name, Clock In, Clock Out, Worked Hours (gross), Paid Hours, Reg Hours, OT Hours, OT Flag, Location Flag, Auto-Closed, Corrected ``
A row whose name ends in (day total) is the day's subtotal for that person, carrying regular and overtime hours; the punch rows above it carry the times. Forgotten punches are settled before the file is built, and a range older than the store's live window merges the archived time records back in, so the file is complete for any range the law requires the store to keep. Each pull is recorded in the store's security log as a payroll export.
What is logged
Every request made with a token writes the token's id, the scope checked, the path and the response status to the store's security log, which the store's owner can view and export. An owner sees exactly what your software read and when.
Webhooks
Not yet. Poll shifts and punches with from and to for now. If you need to be told when something changes, tell us which events matter to you; that is the next thing this API will grow.
Example
`` curl -H "Authorization: Bearer fs_live_05348.<secret>" \ "https://flowstateqsr.com/api/v1/shifts?from=2026-09-07&to=2026-09-13&limit=200" ``
Versioning
The path carries the version. Fields may be added to a response without notice; a field will not be removed or change meaning within /api/v1. The payroll CSV's column set is versioned separately by X-CSV-Version. Breaking changes get a new path and notice by email to every store with a live token.
Security questions about the API are answered on the security overview; reach us at support@flowstateqsr.com.