ResourcesDesktop Auth

Desktop Auth

Authenticate the Close AI desktop app with JWT sign-in, sign-up, token refresh, and global sign-out endpoints — with permissive CORS and Supabase token management.

curl -X POST "https://api.talkturo.com/api/auth/sign-in" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane.chen@acme.co",
    "password": "DeskPass_73A9"
  }'
{
  "success": true,
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.desktop_example_access",
    "refresh_token": "refresh_example_q9K2mL7xP4vN8cR1",
    "expires_in": 3600,
    "expires_at": 1735693200,
    "token_type": "bearer",
    "user": {
      "id": "9f3b6e2a-4d85-4d62-95de-f2ec7e4ac8b1",
      "email": "jane.chen@acme.co",
      "user_metadata": {
        "full_name": "Jane Chen"
      }
    }
  }
}
curl -X POST "https://api.talkturo.com/api/auth/refresh" \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "refresh_example_q9K2mL7xP4vN8cR1"
  }'
{
  "success": true,
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.desktop_example_new_access",
    "refresh_token": "refresh_example_h3M8qT1vL6pW2nZ5",
    "expires_in": 3600,
    "expires_at": 1735696800,
    "token_type": "bearer",
    "user": {
      "id": "9f3b6e2a-4d85-4d62-95de-f2ec7e4ac8b1",
      "email": "jane.chen@acme.co",
      "user_metadata": {
        "full_name": "Jane Chen"
      }
    }
  }
}

Authenticate desktop clients

Use the desktop auth endpoints to sign users in, create accounts, refresh expired access tokens, and revoke sessions. These routes are designed for the Close AI desktop app and any client that authenticates with Supabase JWTs instead of browser cookies.

All desktop auth routes support OPTIONS preflight requests and return permissive CORS headers, including Access-Control-Allow-Origin: *. Every API response uses the same envelope shape: success plus either data or error.

Endpoint summary

MethodPathAuthPurpose
POST/api/auth/sign-inNoneExchange an email and password for session tokens
POST/api/auth/sign-upNoneCreate a new account and optionally return a session
POST/api/auth/sign-outBearer JWTRevoke the current user's refresh tokens globally
POST/api/auth/refreshNoneExchange a refresh token for a new token pair
GET/api/auth/callbackBrowser flowOAuth callback handler
GET/api/auth/confirmBrowser flowEmail confirmation handler

Authentication model

Desktop clients authenticate by sending a Supabase access token in the Authorization header as a Bearer token. After sign-in or refresh, store both the access_token and refresh_token, then use the access token on protected desktop routes.

POST /api/auth/sign-out performs a global sign-out. That invalidates all refresh tokens for the user, not only the token held by the current device.

POST /api/auth/sign-in

Exchange an email address and password for a Supabase session token pair.

Request example

Body parameters

body
emailstring
Required

Email address for the account.

body
passwordstring
Required

Password for the account.

Success response fields

successboolean
Required

Returns true when the request succeeds.

data.access_tokenstring
Required

Short-lived JWT used in the Authorization header for authenticated desktop requests.

data.refresh_tokenstring
Required

Longer-lived token used to obtain a new access token from /api/auth/refresh.

data.expires_ininteger
Required

Lifetime of the access token in seconds.

data.expires_atinteger
Required

Unix timestamp when the access token expires.

data.token_typestring
Required

Token type returned by Supabase. This is typically bearer.

data.userobject
Required

Authenticated user record associated with the token pair.

data.user.idstring
Required

Unique user identifier.

data.user.emailstring
Required

Email address on the authenticated account.

data.user.user_metadataobject
Required

User metadata returned by Supabase.

Error response fields

successboolean
Required

Returns false when authentication fails.

errorstring
Required

Human-readable error message. Invalid credentials return HTTP 401.

POST /api/auth/sign-up

Create a new account with an email address and password. Depending on your Supabase project settings, the endpoint either returns a full session immediately or returns a user object with needs_email_confirm set to true.

Body parameters

body
emailstring
Required

Email address for the new account.

body
passwordstring
Required

Password for the new account.

Response behavior

If email confirmation is not required, the response includes the same token fields returned by sign-in plus needs_email_confirm: false.

If email confirmation is required, the response includes needs_email_confirm: true and a user object, but no active session tokens yet.

Success response fields

successboolean
Required

Returns true when the account is created successfully.

data.needs_email_confirmboolean
Required

Indicates whether the user must confirm their email before receiving or using a session.

data.access_tokenstring

Returned when email confirmation is not required.

data.refresh_tokenstring

Returned when email confirmation is not required.

data.expires_ininteger

Returned when email confirmation is not required.

data.expires_atinteger

Returned when email confirmation is not required.

data.token_typestring

Returned when email confirmation is not required.

data.userobject
Required

Newly created user record.

data.user.idstring
Required

Unique user identifier.

data.user.emailstring
Required

Email address on the new account.

data.user.user_metadataobject

User metadata returned by Supabase, when present.

POST /api/auth/sign-out

Revoke the current user's refresh tokens globally. Send the current access token as a Bearer token in the Authorization header.

This endpoint calls supabase.auth.signOut() with global scope. Signing out from one desktop client invalidates all refresh tokens for that user across devices.

Headers

header
Authorizationstring
Required

Bearer access token in the form Bearer eyJ....

Success response fields

successboolean
Required

Returns true when sign-out completes.

data.okboolean
Required

Returns true after the global sign-out request succeeds.

POST /api/auth/refresh

Exchange a refresh token for a new access token and refresh token pair. Use this endpoint when the current access token expires.

Request example

Body parameters

body
refresh_tokenstring
Required

Refresh token previously returned by sign-in or sign-up.

Success response fields

successboolean
Required

Returns true when the token refresh succeeds.

data.access_tokenstring
Required

New access token for subsequent authenticated requests.

data.refresh_tokenstring
Required

New refresh token. Replace the previously stored refresh token after a successful refresh.

data.expires_ininteger
Required

Lifetime of the new access token in seconds.

data.expires_atinteger
Required

Unix timestamp when the new access token expires.

data.token_typestring
Required

Token type returned by Supabase.

data.userobject
Required

Authenticated user associated with the refreshed session.

Browser handlers

Two related routes support browser-based auth flows. They are part of the auth system, but they are not token exchange endpoints for desktop clients.

GET /api/auth/callback

Handles the Supabase OAuth callback in browser-based sign-in flows.

GET /api/auth/confirm

Handles email confirmation after sign-up.

Typical desktop token flow

Store the refresh token securely and treat the access token as short-lived. A typical desktop client flow looks like this:

Implementation notes

Use the Authorization header only on endpoints that require an access token, such as sign-out and authenticated desktop routes. Sign-in, sign-up, and refresh all accept JSON request bodies and do not require an existing session.

When refresh succeeds, replace both stored tokens. The response may rotate the refresh token, so continuing to use the old refresh token can break later refresh attempts.