Auth API · stations
What an enrolled device shows on its lock screen
POST /api/auth/station/roster
What an enrolled device shows on its lock screen: the station as enrolled, and the people who may unlock it — the organization's active members with a station PIN whose roles open its view.
401 StationCredentialInvalid for an unknown credential or a revoked station, 400 InvalidStation for a malformed body. Appends nothing: a read that carries the device's credential in its body, which a GET could not. No idempotency key: a retry reads the roster again and appends nothing.
Access
Public: The enrolled device's own credential, verified by the route before anything is read: a station signs in as itself, and nobody is signed in on it yet
No token: the link, the claim or the first message is the credential, as the description says.
How scopes come from roles: Scopes and roles. Getting a token: Authentication and app tokens.
Retries
No idempotency key: a retry reads the roster again and appends nothing.
Why every write carries a key: Idempotency and retries.
Facts appended
None. This call records nothing in a journal.
What a fact is: Facts and the journal.
AI agent tool
No agent tool. A station's lock screen, read by the enrolled device under its own credential; no person or agent holds that credential, and an agent works no station.
Connecting an agent: AI agents.
Example
From Set up a station and unlock it with a PIN, step 6: Show the lock screen.
curl -X POST 'https://auth.getmanifold.io/api/auth/station/roster' \
-H 'Content-Type: application/json' \
-d '{
"credential": "stc_Qm9vdGgtMi1pbi10aGUtd2FyZWhvdXNl"
}'const response = await fetch("https://auth.getmanifold.io/api/auth/station/roster", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"credential": "stc_Qm9vdGgtMi1pbi10aGUtd2FyZWhvdXNl"
}),
});
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
const answer = await response.json();{
"credential": "stc_Qm9vdGgtMi1pbi10aGUtd2FyZWhvdXNl"
}{
"station": {
"stationId": "stn_01a1586e-f9f6-7a8b-9c7d-6e5f4a3b2c1d",
"view": "pick-pack",
"locationId": "loc_01a15852-46d1-7a3b-9c0d-1e2f3a4b5c6d",
"name": "Packing bench 2",
"enrolledAt": "2026-08-17T09:00:00.000Z",
"enrolledBy": "usr_01a15869-1d2e-7f3a-8b4c-5d6e7f8a9b0c"
},
"people": [
{
"userId": "usr_01a15869-1d2e-7f3a-8b4c-5d6e7f8a9b0c",
"name": "Avery Lin"
}
]
}The panel writes this call in other languages. It does not send it: Manifold's APIs do not take calls from a web
page on another site, so run the call from your own code or terminal. The whole API as OpenAPI: auth-service.openapi.json. Base URL https://auth.getmanifold.io.
Errors
Every refusal is a status and a JSON body whose _tag names it. A refused call changes nothing.
400
| Refusal | What it means | What to do |
|---|---|---|
InvalidStation reason | The request was refused. reason says why. | Fix the request. Sending it again unchanged gets the same answer. |
401
| Refusal | What it means | What to do |
|---|---|---|
StationCredentialInvalid reason | The request was refused. reason says why. | Nothing changed. |
How refusals work everywhere: Errors.
Used in
- Set up a station and unlock it with a PIN, step 6: Show the lock screen