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"
}'
const response = await fetch("https://api.talkturo.com/api/auth/sign-in", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
email: "jane.chen@acme.co",
password: "DeskPass_73A9"
})
});
const result = await response.json();
console.log(result);
{
"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"
}
}
}
}
{
"success": false,
"error": "Invalid login credentials"
}
curl -X POST "https://api.talkturo.com/api/auth/refresh" \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "refresh_example_q9K2mL7xP4vN8cR1"
}'
const response = await fetch("https://api.talkturo.com/api/auth/refresh", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
refresh_token: "refresh_example_q9K2mL7xP4vN8cR1"
})
});
const result = await response.json();
console.log(result);
{
"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
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | /api/auth/sign-in | None | Exchange an email and password for session tokens |
POST | /api/auth/sign-up | None | Create a new account and optionally return a session |
POST | /api/auth/sign-out | Bearer JWT | Revoke the current user's refresh tokens globally |
POST | /api/auth/refresh | None | Exchange a refresh token for a new token pair |
GET | /api/auth/callback | Browser flow | OAuth callback handler |
GET | /api/auth/confirm | Browser flow | Email 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
Email address for the account.
Password for the account.
Success response fields
Returns true when the request succeeds.
Short-lived JWT used in the Authorization header for authenticated desktop requests.
Longer-lived token used to obtain a new access token from /api/auth/refresh.
Lifetime of the access token in seconds.
Unix timestamp when the access token expires.
Token type returned by Supabase. This is typically bearer.
Authenticated user record associated with the token pair.
Unique user identifier.
Email address on the authenticated account.
User metadata returned by Supabase.
Error response fields
Returns false when authentication fails.
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
Email address for the new account.
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
Returns true when the account is created successfully.
Indicates whether the user must confirm their email before receiving or using a session.
Returned when email confirmation is not required.
Returned when email confirmation is not required.
Returned when email confirmation is not required.
Returned when email confirmation is not required.
Returned when email confirmation is not required.
Newly created user record.
Unique user identifier.
Email address on the new account.
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
Bearer access token in the form Bearer eyJ....
Success response fields
Returns true when sign-out completes.
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
Refresh token previously returned by sign-in or sign-up.
Success response fields
Returns true when the token refresh succeeds.
New access token for subsequent authenticated requests.
New refresh token. Replace the previously stored refresh token after a successful refresh.
Lifetime of the new access token in seconds.
Unix timestamp when the new access token expires.
Token type returned by Supabase.
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.