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.
Authentication Methods
Section titled “Authentication Methods”Querri supports multiple authentication methods:
- JWT Bearer Tokens - Primary authentication method using WorkOS
- Share Links - JWT-free public access to specific resources
- API Keys - For programmatic access (when enabled)
Getting Access Tokens
Section titled “Getting Access Tokens”WorkOS JWT Authentication
Section titled “WorkOS JWT Authentication”All authenticated API requests require a valid JWT token obtained through the WorkOS authentication flow.
Initial Authentication
Section titled “Initial Authentication”# Redirect users to WorkOS authenticationGET https://api.workos.com/sso/authorize ?client_id={CLIENT_ID} &redirect_uri={REDIRECT_URI} &response_type=code &state={RANDOM_STATE}Exchange Authorization Code
Section titled “Exchange Authorization Code”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..."}Making Authenticated Requests
Section titled “Making Authenticated Requests”Include the JWT token in the Authorization header of all API requests:
curl https://api.querri.com/api/projects \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."Authorization Header Format
Section titled “Authorization Header Format”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}Token Refresh
Section titled “Token Refresh”Access tokens expire after 1 hour. Use the refresh token to obtain a new access token without re-authenticating:
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 Link Authentication
Section titled “Share Link Authentication”Share links provide JWT-free access to specific resources. These are useful for sharing dashboards, projects, or files with external users.
Accessing Shared Resources
Section titled “Accessing Shared Resources”# Access via share token in URLGET https://api.querri.com/api/dashboards/{uuid}?share_token={SHARE_TOKEN}
# Or via headercurl 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)
API Keys
Section titled “API Keys”For programmatic access, API keys can be generated from the Querri dashboard.
Generating API Keys
Section titled “Generating API Keys”POST /api/users/api-keysAuthorization: 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"}Using API Keys
Section titled “Using API Keys”curl https://api.querri.com/api/projects \ -H "X-API-Key: qk_live_abc123456789..."Rate Limiting
Section titled “Rate Limiting”The Querri API implements rate limiting to ensure fair usage:
| Authentication Type | Rate Limit | Window |
|---|---|---|
| JWT (authenticated) | 1000 requests | 1 hour |
| API Key | 5000 requests | 1 hour |
| Share Link | 100 requests | 1 hour |
| Unauthenticated | 10 requests | 1 hour |
Rate Limit Headers
Section titled “Rate Limit Headers”All API responses include rate limit information:
X-RateLimit-Limit: 1000X-RateLimit-Remaining: 987X-RateLimit-Reset: 1640003600Rate Limit Exceeded
Section titled “Rate Limit Exceeded”When rate limit is exceeded, the API returns:
HTTP/1.1 429 Too Many RequestsContent-Type: application/jsonRetry-After: 3600
{ "error": "rate_limit_exceeded", "message": "Rate limit exceeded. Please retry after 3600 seconds.", "limit": 1000, "reset_at": "2025-01-15T11:00:00Z"}Error Responses
Section titled “Error Responses”401 Unauthorized
Section titled “401 Unauthorized”Missing or invalid authentication credentials:
{ "error": "unauthorized", "message": "Invalid or expired token"}403 Forbidden
Section titled “403 Forbidden”Valid credentials but insufficient permissions:
{ "error": "forbidden", "message": "Insufficient permissions to access this resource"}Security Best Practices
Section titled “Security Best Practices”- Never expose tokens in client-side code - Store tokens securely server-side
- Use HTTPS only - All API requests must use HTTPS
- Rotate API keys regularly - Set expiration dates and rotate before expiry
- Implement token refresh - Refresh tokens before they expire
- Validate share tokens - Always check expiration and resource scope
- Monitor rate limits - Implement backoff strategies when approaching limits
Cross-Origin Requests (CORS)
Section titled “Cross-Origin Requests (CORS)”The API supports CORS for browser-based applications. Allowed origins must be configured in your organization settings.
Access-Control-Allow-Origin: https://app.querri.comAccess-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONSAccess-Control-Allow-Headers: Authorization, Content-Type, X-API-KeyAccess-Control-Max-Age: 86400Session Management
Section titled “Session Management”JWT sessions are stateless and validated on each request. The backend validates:
- Token signature using WorkOS public keys
- Token expiration (
expclaim) - User existence and active status
- Organization membership
- Resource-level permissions via OpenFGA
No server-side session storage is required.