Skip to content

Authentication

The Querri API uses JWT (JSON Web Token) authentication powered by WorkOS for secure access to all endpoints. This guide covers how to authenticate requests and manage access tokens.

Querri supports multiple authentication methods:

  1. JWT Bearer Tokens - Primary authentication method using WorkOS
  2. Share Links - JWT-free public access to specific resources
  3. API Keys - For programmatic access (when enabled)

All authenticated API requests require a valid JWT token obtained through the WorkOS authentication flow.

Terminal window
# Redirect users to WorkOS authentication
GET https://api.workos.com/sso/authorize
?client_id={CLIENT_ID}
&redirect_uri={REDIRECT_URI}
&response_type=code
&state={RANDOM_STATE}
Terminal window
curl -X POST https://api.workos.com/sso/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "client_abc123",
"client_secret": "sk_live_abc123",
"grant_type": "authorization_code",
"code": "01ABCDEF...",
"redirect_uri": "https://app.querri.com/callback"
}'

Response:

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "refresh_abc123..."
}

Include the JWT token in the Authorization header of all API requests:

Terminal window
curl https://api.querri.com/api/projects \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
Authorization: Bearer {JWT_TOKEN}

The JWT token contains the following claims:

{
"sub": "user_01ABCDEF",
"email": "user@example.com",
"org_id": "org_01ABCDEF",
"iat": 1640000000,
"exp": 1640003600
}

Access tokens expire after 1 hour. Use the refresh token to obtain a new access token without re-authenticating:

Terminal window
curl -X POST https://api.workos.com/sso/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "client_abc123",
"client_secret": "sk_live_abc123",
"grant_type": "refresh_token",
"refresh_token": "refresh_abc123..."
}'

Response:

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}

Share links provide JWT-free access to specific resources. These are useful for sharing dashboards, projects, or files with external users.

Terminal window
# Access via share token in URL
GET https://api.querri.com/api/dashboards/{uuid}?share_token={SHARE_TOKEN}
# Or via header
curl https://api.querri.com/api/dashboards/{uuid} \
-H "X-Share-Token: share_abc123..."

Share tokens are scoped to specific resources and have configurable expiration.

Share Token Validation:

  • Tokens are validated against the resource UUID
  • Expired tokens return 401 Unauthorized
  • Tokens cannot be used for write operations (POST, PUT, DELETE)

For programmatic access, API keys can be generated from the Querri dashboard.

Terminal window
POST /api/users/api-keys
Authorization: Bearer {JWT_TOKEN}
{
"name": "Production Integration",
"scopes": ["projects:read", "projects:write", "connectors:read"],
"expires_at": "2025-12-31T23:59:59Z"
}

Response:

{
"api_key": "qk_live_abc123456789...",
"key_id": "key_01ABCDEF",
"name": "Production Integration",
"scopes": ["projects:read", "projects:write", "connectors:read"],
"created_at": "2025-01-15T10:00:00Z",
"expires_at": "2025-12-31T23:59:59Z"
}
Terminal window
curl https://api.querri.com/api/projects \
-H "X-API-Key: qk_live_abc123456789..."

The Querri API implements rate limiting to ensure fair usage:

Authentication TypeRate LimitWindow
JWT (authenticated)1000 requests1 hour
API Key5000 requests1 hour
Share Link100 requests1 hour
Unauthenticated10 requests1 hour

All API responses include rate limit information:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1640003600

When rate limit is exceeded, the API returns:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 3600
{
"error": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please retry after 3600 seconds.",
"limit": 1000,
"reset_at": "2025-01-15T11:00:00Z"
}

Missing or invalid authentication credentials:

{
"error": "unauthorized",
"message": "Invalid or expired token"
}

Valid credentials but insufficient permissions:

{
"error": "forbidden",
"message": "Insufficient permissions to access this resource"
}
  1. Never expose tokens in client-side code - Store tokens securely server-side
  2. Use HTTPS only - All API requests must use HTTPS
  3. Rotate API keys regularly - Set expiration dates and rotate before expiry
  4. Implement token refresh - Refresh tokens before they expire
  5. Validate share tokens - Always check expiration and resource scope
  6. Monitor rate limits - Implement backoff strategies when approaching limits

The API supports CORS for browser-based applications. Allowed origins must be configured in your organization settings.

Access-Control-Allow-Origin: https://app.querri.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type, X-API-Key
Access-Control-Max-Age: 86400

JWT sessions are stateless and validated on each request. The backend validates:

  1. Token signature using WorkOS public keys
  2. Token expiration (exp claim)
  3. User existence and active status
  4. Organization membership
  5. Resource-level permissions via OpenFGA

No server-side session storage is required.