Authentication & Limits
API keys
Every API call authenticates with a workspace-scoped API key in the Authorization header:
curl -H "Authorization: Bearer kdt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
https://api.konduit.work/v1/me
Keys live in Workspace Settings → API Keys. Treat them like passwords — anyone with a key can read and write everything the key has access to. Revoke and rotate via the same UI.
If billing lapses (payment failure, plan expiry), API keys keep working through the configured grace period (default 14 days), then return 403.
Key types
- Master keys (scopes =
*) — full read/write on every resource. Can edit/delete comments and time entries authored by any user. - Scoped keys — restricted to specific resources or actions (read-only, particular tables, etc.). Can only edit/delete comments and time entries authored by the API key creator.
Plan limits
| Free | Pro | Business | |
|---|---|---|---|
| API access | ❌ | ✅ | ✅ |
| API keys | 0 | 3 | 10 |
| Calls / month | 0 | 50,000 | 500,000 |
| Calls / minute | 0 | 600 | 6,000 |
| Bulk insert / minute (sync) | 0 | 5 | 20 |
| Bulk rows / request (sync) | 0 | 250 | 250 |
| Bulk rows / job (async) | 0 | 50,000 | 50,000 |
| Concurrent bulk jobs | 0 | 1 | 5 |
Each plan also includes an auto-generated master key in addition to the keys above. All keys in a workspace share the same monthly + per-minute call budget — adding keys doesn't increase throughput. To scale call volume, use the API call add-on packs.
CORS
Public API endpoints respond with:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Expose-Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After
This means you can call the API directly from a browser-based integration without a server-side proxy. Authorization comes from the Authorization: Bearer kdt_... header you supply, not the request origin.
Access-Control-Allow-Credentials is never set. Cookies are not sent cross-origin. The Bearer token is the only credential.
Rate limit headers
Every response includes:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Calls allowed per minute for your plan |
X-RateLimit-Remaining |
Calls remaining in the current window |
X-RateLimit-Reset |
Unix timestamp when the window resets |
Retry-After |
Seconds to wait (only sent on 429) |
When you exceed the per-minute or monthly limit, the API returns 429 with a Retry-After header. Use exponential backoff and respect Retry-After.
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1735689660
{ "error": "Rate limit exceeded" }
Bulk insert rate limits
Synchronous bulk inserts (POST /datatables/{tableId}/rows/bulk) have their own per-minute limit (bulkInsertPerMinute) on top of the general per-minute limit. A single sync bulk request can contain up to bulkRowsPerRequest rows.
For larger imports, use the async bulk job endpoint (POST /datatables/{tableId}/jobs/insert) — up to 50,000 rows in one submission, processed in the background, polled via GET /jobs/{jobId}. Concurrent jobs per workspace are capped (Pro=1, Business=5).
For data loads larger than 50k rows in one go, use the in-app CSV import — it bypasses all per-job caps and runs as a background job.
Next
- Errors → — error format, status codes, retry behavior
- Workspace → —
GET /me