Authentication
The Querri Public API uses qk_ API keys for authentication. Every request requires two headers: the API key as a Bearer token and your organization ID.
Required Headers
Section titled “Required Headers”curl https://app.querri.com/api/v1/projects \ -H "Authorization: Bearer qk_live_abc123..." \ -H "X-Tenant-ID: org_..."| Header | Value | Description |
|---|---|---|
Authorization | Bearer qk_... | Your API key |
X-Tenant-ID | org_... | Your organization ID |
Both headers are required on every request. Omitting either returns 401 Unauthorized.
Creating API Keys
Section titled “Creating API Keys”API keys are created in the Querri web app:
- Go to Settings > API Keys
- Click Create API Key
- Enter a name and select scopes
- Copy the key — it is only shown once
The key is displayed once at creation time. Store it securely. If you lose it, revoke the key and create a new one.
You can also manage keys programmatically via the /keys endpoints (requires the admin:keys:manage scope).
Finding Your Organization ID
Section titled “Finding Your Organization ID”Your organization ID (org_...) is shown in Settings > Account and in the API key creation dialog. Copy it from there and set it as an environment variable or pass it directly.
API Key Scopes
Section titled “API Key Scopes”Keys are scoped to limit what they can access. Assign only the scopes each integration needs.
| Scope | Access |
|---|---|
admin:users:read | List and get users |
admin:users:write | Create, update, delete users |
admin:projects:read | List and get projects, steps, step data |
admin:projects:write | Create, update, delete, run projects |
admin:dashboards:read | List and get dashboards |
admin:dashboards:write | Create, update, delete, refresh dashboards |
admin:policies:read | List and get access policies |
admin:policies:write | Create, update, delete policies, assign users |
admin:sources:read | List data sources and connectors |
admin:sources:write | Create, update, delete sources, trigger sync |
admin:files:read | List and get files |
admin:files:write | Upload and delete files |
admin:permissions:read | List sharing settings |
admin:permissions:write | Share and revoke access to projects and dashboards |
admin:keys:manage | Create, list, revoke API keys |
admin:usage:read | View usage metrics |
admin:audit:read | Query audit log |
data:read | Read data sources and execute queries |
data:write | Write to data sources |
embed:session:create | Create embed sessions |
Wildcard scopes are supported: admin:users:* grants both read and write for users. admin:* grants all admin scopes.
Key Restrictions
Section titled “Key Restrictions”API keys support optional restrictions for defense-in-depth:
- IP allowlist — Restrict which IP addresses can use the key
- Source scope — Limit which data sources the key can access (by source ID)
- Bound user — Tie the key to a specific user’s permissions
- Access policies — Apply row-level security policies to all requests made with the key
- Rate limit — Per-minute request cap (in addition to the default org-wide limit)
These are configured when creating the key in the UI or via the API.
Rate Limiting
Section titled “Rate Limiting”All API responses include rate limit headers:
X-RateLimit-Limit: 60X-RateLimit-Remaining: 58X-RateLimit-Reset: 1708300800When the limit is exceeded, the API returns 429 Too Many Requests with a Retry-After: 60 header. Back off and retry after the indicated period.
Error Responses
Section titled “Error Responses”401 Unauthorized
Section titled “401 Unauthorized”Missing, invalid, or expired API key:
{ "error": { "type": "authentication_error", "message": "Invalid API key" }}403 Forbidden
Section titled “403 Forbidden”Valid key but insufficient scopes or IP not in allowlist:
{ "error": { "type": "permission_error", "message": "API key does not have the required scope: admin:projects:read" }}Security Best Practices
Section titled “Security Best Practices”- Never expose keys in client-side code — API keys are server-side secrets. Use embed sessions for browser-based access.
- Use minimal scopes — Grant only the scopes each integration needs.
- Set IP allowlists — If your integration runs from known IPs, restrict the key.
- Rotate keys regularly — Revoke old keys and create new ones periodically.
- Use environment variables — Store keys in
QUERRI_API_KEY, not in source code. - Monitor the audit log — Review API key usage in Settings > Audit Log or via
GET /audit/events.