Skip to content

Authentication

BitMarks uses OAuth 2.0 via WorkOS AuthKit for authentication. This provides secure, industry-standard authentication with support for social logins and enterprise SSO.

┌─────────┐ ┌─────────────┐ ┌─────────┐ ┌─────────────┐
│ User │────▶│ Your App │────▶│ BitMarks│────▶│ WorkOS │
│ │ │ │ │ API │ │ AuthKit │
└─────────┘ └─────────────┘ └─────────┘ └─────────────┘
│ │ │ │
│ 1. Click Login │ │ │
│────────────────▶│ │ │
│ │ 2. POST /login │ │
│ │────────────────▶│ │
│ │ │ │
│ │ 3. authorizationUrl │
│ │◀────────────────│ │
│ │ │ │
│ 4. Redirect to authorizationUrl │ │
│◀────────────────│ │ │
│ │ │ │
│ 5. Login at WorkOS │ │
│─────────────────────────────────────────────────────▶
│ │ │ │
│ 6. Redirect to callback with code│ │
│◀─────────────────────────────────────────────────────
│ │ │ │
│ 7. GET /callback?code=... │ │
│────────────────────────────────────▶ │
│ │ │ 8. Exchange │
│ │ │────────────────▶│
│ │ │ 9. Tokens │
│ │ │◀────────────────│
│ │ │ │
│ 10. Set cookies & redirect │ │
│◀─────────────────────────────────── │
  1. Start the OAuth flow by calling the login endpoint:

    Terminal window
    POST /api/v1/auth/login
    Content-Type: application/json
    {
    "returnTo": "/dashboard" // Optional: where to redirect after login
    }

    Response:

    {
    "authorizationUrl": "https://authkit.workos.com/sso/authorize?client_id=..."
    }
  2. Redirect the user to the authorizationUrl. They’ll see the WorkOS login page where they can:

    • Sign in with email/password
    • Use social login (Google, GitHub, etc.)
    • Use enterprise SSO (if configured)
  3. After authentication, WorkOS redirects to your callback URL with an authorization code:

    GET /api/v1/auth/callback?code=AUTH_CODE&state=/dashboard

    The API automatically:

    • Exchanges the code for tokens
    • Creates the user in the database (if first login)
    • Sets session cookies
    • Redirects to the state URL (your returnTo value)
  4. All subsequent requests should include the bitmarks_session cookie:

    Terminal window
    GET /api/v1/sync/status
    Cookie: bitmarks_session=YOUR_SESSION_TOKEN

    In JavaScript with fetch:

    fetch('https://app.bitmarks.sh/api/v1/sync/status', {
    credentials: 'include' // Includes cookies automatically
    });
CookieDurationPurpose
bitmarks_session7 daysAccess token for API requests
bitmarks_refresh30 daysRefresh token for obtaining new access tokens
Set-Cookie: bitmarks_session=TOKEN;
HttpOnly;
Secure;
SameSite=Lax;
Domain=.bitmarks.sh;
Max-Age=604800

Verify if the user is authenticated and get their info:

Terminal window
GET /api/v1/auth/session
Cookie: bitmarks_session=YOUR_TOKEN

When the access token expires, use the refresh token to obtain a new one:

Terminal window
POST /api/v1/auth/refresh
Cookie: bitmarks_refresh=YOUR_REFRESH_TOKEN

Success Response:

{
"success": true
}

New bitmarks_session cookie is automatically set.

Error Response (401):

{
"error": "No refresh token"
}

Clear session cookies and end the session:

Terminal window
POST /api/v1/auth/logout

Response:

{
"success": true
}

Both bitmarks_session and bitmarks_refresh cookies are cleared.

  1. Always use HTTPS - Session cookies are marked Secure and won’t be sent over HTTP
  2. Handle token expiration - Implement automatic refresh before requests
  3. Logout on errors - If you receive persistent 401s, clear local state and re-authenticate
  4. Secure storage - The browser handles cookie storage securely; don’t manually store tokens
async function apiRequest(url, options = {}) {
let response = await fetch(url, {
...options,
credentials: 'include'
});
// If unauthorized, try refreshing the token
if (response.status === 401) {
const refreshResponse = await fetch('/api/v1/auth/refresh', {
method: 'POST',
credentials: 'include'
});
if (refreshResponse.ok) {
// Retry the original request
response = await fetch(url, {
...options,
credentials: 'include'
});
} else {
// Refresh failed, redirect to login
window.location.href = '/login';
return;
}
}
return response;
}
StatusErrorMeaning
401Authentication requiredNo session cookie provided
401Invalid or expired sessionSession token is invalid or expired
401No refresh tokenAttempting to refresh without a refresh token
401Failed to refresh tokenRefresh token is invalid or expired
500Failed to initiate loginError communicating with WorkOS

The API allows credentials from configured origins:

  • Production: https://app.bitmarks.sh
  • Extension: Chrome extension origin

For local development, configure CORS_ORIGIN environment variable.