Skip to content

Auth

Authentication endpoints handle the OAuth 2.0 login flow with WorkOS AuthKit.


POST /api/v1/auth/login

Starts the OAuth login flow and returns the authorization URL.

None required.

FieldTypeRequiredDescription
returnTostringNoURL to redirect to after login (default: /)
Terminal window
curl -X POST https://app.bitmarks.sh/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"returnTo": "/dashboard"}'

Status: 200 OK

{
"authorizationUrl": "https://authkit.workos.com/sso/authorize?client_id=..."
}

Status: 500 Internal Server Error

{
"error": "Failed to initiate login"
}

GET /api/v1/auth/callback

Handles the OAuth callback from WorkOS after user authentication.

None required.

ParamTypeRequiredDescription
codestringYesAuthorization code from WorkOS
statestringNoReturn URL (default: /)
  1. Exchanges authorization code for tokens with WorkOS
  2. Creates user in database if first login
  3. Sets session cookies
  4. Redirects to return URL

Status: 302 Found

Redirects to the URL specified in state parameter.

Headers:

Set-Cookie: bitmarks_session=TOKEN; HttpOnly; Secure; SameSite=Lax; Max-Age=604800
Set-Cookie: bitmarks_refresh=TOKEN; HttpOnly; Secure; SameSite=Lax; Max-Age=2592000
Location: /dashboard

On error, redirects to /login?error=<message>


POST /api/v1/auth/logout

Clears session cookies and ends the user session.

None required (clears any existing session).

Terminal window
curl -X POST https://app.bitmarks.sh/api/v1/auth/logout

Status: 200 OK

{
"success": true
}

Both bitmarks_session and bitmarks_refresh cookies are cleared.

Status: 500 Internal Server Error

{
"error": "Failed to logout"
}

GET /api/v1/auth/session

Returns current session information.

Cookie-based (checks session validity).

Terminal window
curl https://app.bitmarks.sh/api/v1/auth/session \
-b "bitmarks_session=YOUR_TOKEN"

Status: 200 OK

{
"authenticated": true,
"user": {
"user_id": "user_01ABC123",
"email": "user@example.com",
"name": "John Doe",
"avatar_url": "https://avatars.example.com/user.png",
"email_verified": true
}
}

Status: 401 Unauthorized

{
"authenticated": false
}
FieldTypeDescription
user_idstringUnique user identifier
emailstringUser’s email address
namestringUser’s display name
avatar_urlstringURL to user’s avatar image
email_verifiedbooleanWhether email is verified

POST /api/v1/auth/refresh

Uses the refresh token to obtain a new access token.

Requires bitmarks_refresh cookie.

Terminal window
curl -X POST https://app.bitmarks.sh/api/v1/auth/refresh \
-b "bitmarks_refresh=YOUR_REFRESH_TOKEN"

Status: 200 OK

{
"success": true
}

A new bitmarks_session cookie is set automatically.

Status: 401 Unauthorized

{
"error": "No refresh token"
}

or

{
"error": "Failed to refresh token"
}

CookieDurationPurpose
bitmarks_session7 daysAccess token for API requests
bitmarks_refresh30 daysRefresh token for obtaining new access tokens
  • HttpOnly - Not accessible via JavaScript
  • Secure - Only sent over HTTPS (production)
  • SameSite=Lax - CSRF protection
  • Domain=.bitmarks.sh - Shared across subdomains (production)

async function authenticatedFetch(url, options = {}) {
let response = await fetch(url, {
...options,
credentials: 'include'
});
if (response.status === 401) {
// Try to refresh the token
const refreshResponse = await fetch('/api/v1/auth/refresh', {
method: 'POST',
credentials: 'include'
});
if (refreshResponse.ok) {
// Retry original request
response = await fetch(url, {
...options,
credentials: 'include'
});
} else {
// Redirect to login
window.location.href = '/login';
throw new Error('Session expired');
}
}
return response;
}