AuthService
ApproveWorkspaceSignIn
Section titled “ApproveWorkspaceSignIn”POST /spin.v1.AuthService/ApproveWorkspaceSignIn
Request
| Field | Type | What it is |
|---|---|---|
request | string | From BeginWorkspaceSignInResponse.approve_url. |
Response
| Field | Type | What it is |
|---|---|---|
callbackUrl | string | The workspace host’s callback with the one-time code, for the browser to be sent to. |
BeginWorkspaceSignIn
Section titled “BeginWorkspaceSignIn”POST /spin.v1.AuthService/BeginWorkspaceSignIn
A sign-in on a workspace’s host, done by the dashboard. The proxy begins it and sends the browser to the dashboard, which approves it for whoever is signed in there and sends the browser back with a one-time code; the proxy completes it with that code and the binding it gave the same browser. The identity provider is only ever told the dashboard’s callback.
Request
| Field | Type | What it is |
|---|---|---|
host | string | The workspace’s host the browser asked for, as the proxy received it: <name>.ws.<domain>. The code comes back to this host and to no other. |
returnPath | string | Where on that host the browser goes once it is signed in: a path, never a URL. |
Response
| Field | Type | What it is |
|---|---|---|
approveUrl | string | The dashboard’s page that approves this sign-in, for the browser to be sent to. |
binding | string | A secret for the browser that began this sign-in, kept where only the proxy reads it: CompleteWorkspaceSignIn requires it with the code, so a code opened in another browser - one somebody was sent a link to - signs nobody in. |
CheckDeviceLogin
Section titled “CheckDeviceLogin”POST /spin.v1.AuthService/CheckDeviceLogin
Check device login status (CLI polls this) Returns session token once user has completed login and entered the code
Request
| Field | Type | What it is |
|---|---|---|
deviceCode | string | The device_code from StartDeviceLogin |
Response
| Field | Type | What it is |
|---|---|---|
status | DeviceLoginStatus | Status of the device login |
user | User | Only set when status is DEVICE_LOGIN_STATUS_COMPLETE |
sessionToken | string | |
expiresAt | Timestamp |
CompleteLogin
Section titled “CompleteLogin”POST /spin.v1.AuthService/CompleteLogin
Complete login (callback from IdP)
Request
| Field | Type | What it is |
|---|---|---|
code | string | OAuth/OIDC code |
state | string | CSRF state token (contains provider info) |
binding | string | StartLoginResponse.binding for this state |
Response
| Field | Type | What it is |
|---|---|---|
user | User | |
sessionToken | string | |
expiresAt | Timestamp |
CompleteWorkspaceSignIn
Section titled “CompleteWorkspaceSignIn”POST /spin.v1.AuthService/CompleteWorkspaceSignIn
Request
| Field | Type | What it is |
|---|---|---|
code | string | |
binding | string | BeginWorkspaceSignInResponse.binding, as the browser presented it. |
host | string | The host the callback arrived on, which must be the one the sign-in began on. |
Response
| Field | Type | What it is |
|---|---|---|
sessionToken | string | |
expiresAt | Timestamp | |
returnPath | string |
ConfirmDeviceLogin
Section titled “ConfirmDeviceLogin”POST /spin.v1.AuthService/ConfirmDeviceLogin
Complete device login (dashboard calls this after user enters code) Requires authentication - links the device code to the current user
Request
| Field | Type | What it is |
|---|---|---|
userCode | string | The user code entered by the user (e.g., “ABCD-1234”) |
Response
No fields: {}.
CreateAPIKey
Section titled “CreateAPIKey”POST /spin.v1.AuthService/CreateAPIKey
Create API key
Request
| Field | Type | What it is |
|---|---|---|
name | string | |
scopes | list of string | e.g., [“workspace:read”, “workspace:write”] |
expiresAt | Timestamp |
Response
| Field | Type | What it is |
|---|---|---|
apiKey | APIKey | |
secret | string | Only shown once |
GetCurrentUser
Section titled “GetCurrentUser”POST /spin.v1.AuthService/GetCurrentUser
Get current user info
Request
No fields: {}.
Response
| Field | Type | What it is |
|---|---|---|
user | User | |
controlPlaneVersion | string | The release of the control plane that answered, which is the release of the dashboard asking: the bundle is served from inside that binary. It rides here rather than on an endpoint of its own because every session asks this once, and because a version an installation will be matched against known flaws by is not something to hand out unauthenticated. |
ListAPIKeys
Section titled “ListAPIKeys”POST /spin.v1.AuthService/ListAPIKeys
List API keys
Request
| Field | Type | What it is |
|---|---|---|
page | PageRequest |
Response
| Field | Type | What it is |
|---|---|---|
apiKeys | list of APIKey | |
page | PageResponse |
ListIdentityProviders
Section titled “ListIdentityProviders”POST /spin.v1.AuthService/ListIdentityProviders
List available identity providers (for login page) Always includes built-in GitHub provider; additional OIDC providers from database
Request
No fields: {}.
Response
| Field | Type | What it is |
|---|---|---|
providers | list of IdentityProvider |
Logout
Section titled “Logout”POST /spin.v1.AuthService/Logout
Logout (invalidate session)
Request
No fields: {}.
Response
No fields: {}.
RevokeAPIKey
Section titled “RevokeAPIKey”POST /spin.v1.AuthService/RevokeAPIKey
Revoke API key
Request
| Field | Type | What it is |
|---|---|---|
id | string |
Response
No fields: {}.
SearchUsers
Section titled “SearchUsers”POST /spin.v1.AuthService/SearchUsers
Search users by name or email (for team member selection, workspace sharing)
Request
| Field | Type | What it is |
|---|---|---|
query | string | Search by name or email |
limit | integer (int32) | Max results (default 10) |
excludeTeamId | string | Exclude users already in this team |
Response
| Field | Type | What it is |
|---|---|---|
users | list of User |
StartDeviceLogin
Section titled “StartDeviceLogin”POST /spin.v1.AuthService/StartDeviceLogin
Start device login flow (for CLI when OAuth redirect is not available) Returns a user code and verification URL. User visits URL and enters code.
Request
| Field | Type | What it is |
|---|---|---|
identityProviderId | string | Optional: use default if empty |
Response
| Field | Type | What it is |
|---|---|---|
deviceCode | string | Secret code for CLI to poll with |
userCode | string | Short code user enters (e.g., “ABCD-1234”) |
verificationUrl | string | URL user visits to login |
expiresIn | integer (int32) | Seconds until codes expire |
interval | integer (int32) | Seconds between poll attempts |
StartLogin
Section titled “StartLogin”POST /spin.v1.AuthService/StartLogin
Start login flow with a specific identity provider Use “github” for built-in GitHub auth, or IdP ID for dynamic providers
Request
| Field | Type | What it is |
|---|---|---|
identityProviderId | string | ID of the identity provider to use |
redirectUri | string | Where the identity provider sends the code: the dashboard’s /auth/callback, over https. Anything else is refused. |
Response
| Field | Type | What it is |
|---|---|---|
authUrl | string | URL to redirect user to |
state | string | CSRF state token |
binding | string | A secret for the client that began this sign-in, and for nobody else: CompleteLogin requires it with the state. The state and the code come back in a URL, which somebody who signed in to their own account can send to anybody - and without this, whoever opens it is signed in as them. Kept where only this client reads it, never in a URL. |
Generated by task reference from spin/internal/controlplane/apidocs/spin.v1.openapi.json at 8eee32b9d.
Documents Spinbox v20261019.02. This page as Markdown, for a model or a terminal.

