Authentication
JWT Authentication
Section titled “JWT Authentication”Use bearer token for user-scoped internal routes.
Header:
Authorization: Bearer <access_token>Token lifecycle endpoints:
POST /api/v1/auth/loginPOST /api/v1/auth/refreshPOST /api/v1/auth/logout
API Key Authentication
Section titled “API Key Authentication”Use API key header for public audience routes:
X-API-Key: <raw_api_key>Requirements for API key auth:
- Route must be tagged as public audience.
tenant_idandworkspace_idmust be resolvable (typically in path).- Key must be active, not expired, not revoked.
- Key scopes must allow the requested permission.
Creating API Keys
Section titled “Creating API Keys”Create keys via JWT-authenticated endpoint:
POST /api/v1/tenants/{tenant_id}/workspaces/{workspace_id}/integrations/api-keys
Key facts:
raw_keyis returned once at creation.- Key scopes are validated against allowed public resources.
- Default scopes:
invoice:read,party:read,product:read,report:read,webhooks:read. - Allowed resources:
invoice,party,product,report,webhooks. - Optional
rate_limit_per_minuteoverrides the subscription tier default.
Rate Limits
Section titled “Rate Limits”Each API key is rate-limited based on your subscription tier:
| Tier | Requests/minute |
|---|---|
| Starter | 60 |
| Professional | 300 |
| Enterprise | 1,000 |
Exceeding the limit returns 429 Too Many Requests with a Retry-After: 60 header.
You can set a custom per-key limit (via rate_limit_per_minute at creation) to override the tier default.
Scope Evaluation
Section titled “Scope Evaluation”A request is allowed when either:
- exact scope exists (e.g.,
invoice:read), or - wildcard for resource exists (e.g.,
invoice:*).
Otherwise, API returns 403 scope denial.
Route Audience Behavior
Section titled “Route Audience Behavior”If X-API-Key is supplied on non-public routes, auth is rejected.