Authentication
The three kinds of access token the API accepts, how devices get theirs, and how to choose the organisation on Mojo Up AI Cloud.
Every endpoint says which kinds of token it accepts. Send the token in the Authorization header.
Device tokens
Workbenches and nodes have access of their own, separate from any person's. They get it with the device-code flow (RFC 8628):
- The device calls
POST /relay/v1/device/codeand shows the person theuser_code, withverification_uri(or opensverification_uri_complete, which has the code filled in). - A person signed in to the organisation approves the code in the console. A node waits for someone allowed to approve nodes.
- Meanwhile the device polls
POST /relay/v1/device/tokeneveryintervalseconds. Until approval it getsauthorization_pending; polling too fast getsslow_down. On approval it receives an access token, a refresh token, its device id and the scopes granted. - When the access token expires, the device exchanges its refresh token at
POST /relay/v1/token.
A node can also join with a join key an administrator created, at POST /relay/v1/device/join, with no code and no waiting.
Device tokens are random strings with recognisable prefixes: aioe_at_ for access tokens and aioe_rt_ for refresh tokens. The platform stores only their hashes.
Authorization: Bearer aioe_at_…DPoP: binding a token to the device
A device can bind its tokens to a key it holds (DPoP, RFC 9449). It sends the key's RFC 7638 thumbprint as dpop_jkt when it asks for a code, and a DPoP proof signed by that key with the token poll. The tokens come back with token_type: "DPoP". From then on, every request sends the token with the DPoP scheme and a fresh proof:
Authorization: DPoP aioe_at_…
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIs…The discovery document's dpopSigningAlgs lists the proof algorithms the platform accepts (ES256 and EdDSA). A request with a bound token but no valid proof is refused with invalid_dpop_proof.
People on self-hosted AIOE
On self-hosted AIOE, a person's token comes from the organisation's identity provider (Microsoft Entra ID, Okta or another OpenID Connect provider), requested with the auth.clientId and auth.apiScope from the discovery document. The API verifies it against the provider's published keys, and the token's issuer selects the organisation.
Authorization: Bearer eyJ0eXAiOiJKV1Qi…People on Mojo Up AI Cloud
Mojo Up AI Cloud issues its own tokens. A client signs a person in through /auth/v1/start (a provider) or /auth/v1/email/start (an emailed code), using PKCE, and exchanges the resulting one-time code at POST /auth/v1/token:
- access tokens last 15 minutes;
- refresh tokens last 30 days and are replaced on every use; reusing an old one ends the session;
POST /auth/v1/logoutends the session.
Sign-in redirects only go to addresses registered for the client (console or mobile).
Choosing the organisation
A person's Cloud session is not tied to one organisation. Where a request acts for an organisation, name it in a header:
Authorization: Bearer <Cloud access token>
X-Aioe-Organisation: <organisation id>The organisation ids a person belongs to are in GET /cloud/v1/me. The platform checks membership on every request. Device tokens already carry their organisation and need no header.
Errors
Errors are JSON with an error code, and often a message or error_description in plain words:
{ "error": "forbidden", "message": "only the organisation's owners and admins can do this" }| Status | Usually means |
|---|---|
400 | The request did not match the schema, or a code or token is wrong or expired. |
401 | No valid token. |
403 | Signed in, but not allowed to do this. |
404 | Not found, or not yours to see. The API says "not found" rather than reveal that something exists in another organisation. |
409 | It conflicts with the current state, for example removing a team's last owner. |
429 | Too many requests. Wait, then try again. |