Authentication

This guide explains how to authenticate with our GraphQL API, obtain and use tokens, refresh sessions, and handle common errors.

  • our API uses short-lived access tokens (JWT) and longer-lived refresh tokens.
  • You can carry the access token in the Authorization header or rely on secure cookies set during login.

Login

Use the login mutation with user credentials. On success you’ll receive:

  • token: access token (JWT)
  • refreshToken: refresh token
  • expiresIn: access token lifetime in seconds (typically 900)
mutation Login($email: String!, $password: String!) {
    login(email: $email, password: $password) {
        token
        refreshToken
        expiresIn
    }
}

Tip: If you are using a browser client, the server may also set secure cookies for you: _trp (access) and _trpr (refresh).

Sending Authenticated Requests

Include the access token as a bearer token in each request.

curl -X POST "$GRAPHQL_ENDPOINT" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "query": "query { user { id email } }"
  }'

If you are using cookies (browser flows), requests will be authenticated automatically when the cookies are present and valid.

Token Lifetimes

  • Access token: ~15 minutes (returns expiresIn: 900)
  • Refresh token: ~12 hours

Plan to refresh the access token before it expires, or handle 401/Unauthorized responses by triggering a refresh.

Refreshing the Access Token

Use the refreshToken mutation to obtain a new access token. You can supply the refresh token explicitly, or omit it and rely on the refresh cookie if set.

mutation RefreshToken($refreshToken: String) {
    refreshToken(refreshToken: $refreshToken) {
        token
        refreshToken
        expiresIn
    }
}

Notes:

  • If you pass refreshToken, it must match the stored refresh token for your user.
  • If omitted, the server will read the refresh token from the secure cookie when available.
  • The refresh token rotates on every use. Each call to refreshToken returns a new refresh token alongside the new access token. Always persist the refreshToken value from the response and use it for the next refresh; do not keep reusing the original token from login.
  • There is no session limit. Logging in again for the same account (for example, a second worker process or a second browser tab) does not invalidate the first session's tokens. Concurrent sessions for one account are supported.

Cookies vs Headers

  • Headers: Works in any client. Send Authorization: Bearer <token>.
  • Cookies: In browser flows, secure cookies (_trp for access, _trpr for refresh) may be set. They are Secure and SameSite=Strict.
  • You can mix approaches: use cookies in the browser and still attach the Authorization header for API calls from your backend.

Error Handling

Common authentication errors and suggested actions:

  • Unauthorized: No token provided: Ensure the Authorization header or access cookie is present.
  • Unauthorized: Token verification failed: Access token is invalid or expired; refresh and retry.
  • No refresh token provided: Pass the refresh token or ensure the refresh cookie is set.
  • Invalid refresh token: Token mismatch or tampering detected; prompt for re-login.
  • Refresh token expired: Refresh session has ended; prompt for re-login.
  • Incorrect email or password (from login); Credentials are wrong; prompt for re-entry. As observed today, this error is returned with extensions.code: INTERNAL_SERVER_ERROR, not a dedicated UNAUTHENTICATED code. Match on the error message, not on extensions.code, when handling a failed login; do not branch client logic on that code for this mutation.

Sign-out

  • Clients should remove stored tokens (and clear cookies if applicable). If you need server-side revocation of a refresh token, contact support for guidance.

Best Practices

  • Prefer short-lived access tokens and refresh as needed.
  • Store tokens securely; avoid exposing them to untrusted scripts.
  • In SPAs, prefer secure, HTTP-only cookies for refresh; attach access tokens via header for API calls.
  • Handle 401 by attempting a single refresh, then redirect to login if it fails.

Did this page help you?
All rights reserved © 2025 deal-engine.com.