CLI session endpoints
The routes behind geni login, geni workspace, geni exec, and geni browser. They take a CLI session only, never an API key.
Four route families exist for geni itself. They need a switchable, revocable session with a person behind it, so an API key is refused with 401 Authentication required: the key simply is not a session, and the route says nothing more. They are documented here so the shape of the CLI is not a mystery, not as an integration surface.
The message 403 This endpoint requires a CLI session does exist, but it guards exactly one other mount reached through a different prefix.
A CLI session (geni_rs_…) is minted by the device-code flow, lives in ~/.config/geni/runner-session.json, and is bound to one account with a switchable active workspace. Everything else under /v1 accepts it as a full-access member credential.
Device-code login (/v1/auth)
| Method | Path | Auth | Does |
|---|---|---|---|
| POST | /v1/auth/device-code | none | Start a login. Returns userCode, deviceCode, verificationUri, intervalSeconds, expiresAt. |
| GET | /v1/auth/device-code/:userCode | none | The code's status: pending, approved, denied, expired. Read-only. |
| POST | /v1/auth/device-code/:userCode/poll | none | CLI-only poll. On approved, consumes and returns the one-shot sessionToken. |
| POST | /v1/auth/device-code/:userCode/approve | dashboard session | The browser side. Body membershipId. |
| POST | /v1/auth/device-code/:userCode/deny | dashboard session | The browser side. |
| GET | /v1/auth/me | CLI session | The user and active workspace behind geni auth status. |
| POST | /v1/auth/logout | CLI session | Revoke the session. |
Codes live about ten minutes. The unauthenticated routes are limited to 600 requests per minute per IP.
Workspaces (/v1/workspaces)
| Method | Path | Does |
|---|---|---|
| GET | /v1/workspaces | Every workspace the account belongs to, with isActive. |
| GET | /v1/workspaces/members | Active members of the active workspace. ?query= and ?page= (25 per page). |
| POST | /v1/workspaces/switch | Re-point the session at another membership. Body membershipId. |
Exec (/v1/exec)
| Method | Path | Does |
|---|---|---|
| POST | /v1/exec/resolve | Resolve declared credentials for one geni exec bash call: env vars, values to scrub, a fresh platform key, and the egress policy. Body credentials: [{ id, reason }], up to 50. |
The subprocess runs on the operator's machine. The server only hands back env vars and redaction values, and writes the credential access log. A credential the member cannot use fails the whole call with 403; a credential that resolved to an empty token (an expired OAuth refresh) is reported in errors[] without aborting.
Browser (/v1/browser)
| Method | Path | Does |
|---|---|---|
| GET | /v1/browser/profiles | The member's browser plus shared ones, with saved logins. |
| POST | /v1/browser/sessions | Open a hosted browser for local CDP scripts. Optional profileId. |
| POST | /v1/browser/sessions/:token/touch | Refresh the liveness lease. 404 once the session is gone. |
| POST | /v1/browser/sessions/:token/close | Save the login and stop billing. |
| POST | /v1/browser/profiles/:id/report-login | Record a listed login as active or logged_out. |
| POST | /v1/browser/profiles/:id/login-session | Start the interactive login handoff. Owner only. |
| POST | …/login-session/:token/touch | Keep the handoff alive. |
| POST | …/login-session/:token/check | Ask whether the site is signed in. Starts an agent check. |
| GET | …/login-session/:token/outcome | The last check's verdict. Poll until isRunning is false. |
| POST | …/login-session/:token/finish | Verify and save the login. |
| POST | …/login-session/:token/cancel | Abandon the handoff. |
Sessions bill browser time, so a stateless key has no business here. See geni browser for the flow these back.