Auth API · printAgents
Exchange a print agent's credential for its device token
POST /api/auth/print-agent/token
Exchange a print agent's credential for its device token: fifteen minutes, subject device:<agentId>, the agent's organization and the printAgent claim naming the agent and the location it was enrolled at — no person and no roles, so every service gives it only what a print agent holds (its own print jobs, read and reported).
The agent calls it again before the token lapses — its heartbeat: each call stamps the agent's lastSeenAt and keeps the build it reports (agent: its version, update channel and the newest version its updater found), which the organization's list shows so a person sees an agent that is behind. 401 PrintAgentCredentialInvalid for an unknown credential or a revoked agent. Appends nothing: a mint changes no state. No idempotency key: a retry mints another short-lived token and appends nothing.
Access
Public: The print agent's own credential, verified by the route before anything is read: an agent signs in as itself, with no person behind it
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 mints another short-lived token 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. The print agent's own protocol, exchanging its credential for a device token at the site; no person or agent holds that credential, and a token is never handed to an agent.
Connecting an agent: AI agents.
Example
curl -X POST 'https://auth.getmanifold.io/api/auth/print-agent/token' \
-H 'Content-Type: application/json' \
-d '{
"credential": "pag_01a1a3c2-5d6e-7f80-9a1b-2c3d4e5f6a7b.Rm9yLXRoZS1kaXNwYXRjaC16ZWJyYS1vbmx5",
"agent": {
"version": "1.3.0",
"channel": "latest",
"available": "1.4.0"
}
}'const response = await fetch("https://auth.getmanifold.io/api/auth/print-agent/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"credential": "pag_01a1a3c2-5d6e-7f80-9a1b-2c3d4e5f6a7b.Rm9yLXRoZS1kaXNwYXRjaC16ZWJyYS1vbmx5",
"agent": {
"version": "1.3.0",
"channel": "latest",
"available": "1.4.0"
}
}),
});
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
const answer = await response.json();{
"credential": "pag_01a1a3c2-5d6e-7f80-9a1b-2c3d4e5f6a7b.Rm9yLXRoZS1kaXNwYXRjaC16ZWJyYS1vbmx5",
"agent": {
"version": "1.3.0",
"channel": "latest",
"available": "1.4.0"
}
}{
"token": "eyJhbGciOiJFZERTQSJ9.eyJwcmludEFnZW50Ijp0cnVlfQ.ZGV2aWNlLXRva2Vu",
"expiresAt": "2026-10-30T02:20:00.000Z",
"tenantId": "org_01a1586e-f9f6-7a8b-9c7d-6e5f4a3b2c1d",
"printAgent": {
"agentId": "pag_01a1a3c2-5d6e-7f80-9a1b-2c3d4e5f6a7b",
"locationId": "loc_01a15852-46d1-7a3b-9c0d-1e2f3a4b5c6d"
}
}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.
401
| Refusal | What it means | What to do |
|---|---|---|
PrintAgentCredentialInvalid reason | The print agent's credential is unknown, or the agent was revoked. | Enrol the agent again from Settings › Printing. |
How refusals work everywhere: Errors.