step 05
API keys & the v1 API
Automate crawling, dataset generation and training via the REST API. Create scoped API keys for programmatic access.
01
Creating API keys
Go to Dashboard → API Keys and click Create Key. You’ll configure three things.
| Field | What it does |
|---|---|
| Name | A label to identify the key (e.g. "CI/CD Pipeline" or "Staging"). |
| Permissions | Scope the key to specific actions: crawl, dataset, train, or * for all. |
| Expiration | Optionally set the key to auto-expire after 30, 60, 90 or 365 days. |
Important
Each key has two parts: a key ID (knh_kid_...), which is safe to log, and a secret (knh_sec_...), which you use for authentication.
02
Authentication
Pass your secret key in the X-API-Key header on every request.
terminal
curl -X POST https://api.kanha.ai/api/v1/pages/{page_id}/recrawl \
-H "X-API-Key: knh_sec_your_secret_here" \
-H "Content-Type: application/json" \
-d '{}'The API key is tied to a team. All resources accessed via the key are scoped to that team, so there is no need to pass a team ID header separately.
You can also use a JWT token with Authorization: Bearer ... and X-Team-Id headers instead of an API key. JWT auth has all permissions implicitly.
03
V1 endpoints
post/api/v1/pages/{page_id}/recrawl
Re-crawl a page to update its indexed content. Requires crawl permission. Send a JSON object in the request body. The render_js field is optional and defaults to false.
request body
{
"render_js": false
}response
{
"success": true,
"data": {
"page_id": "uuid",
"status": "queued",
"auth": { "method": "api_key", "key_id": "knh_kid_..." }
}
}post/api/v1/sites/{site_id}/datasets
Generate a QA training dataset from all indexed pages in a site. Requires dataset permission. No request body needed.
generate dataset
{
"success": true,
"data": {
"dataset_id": "uuid",
"status": "completed",
"auth": { "method": "api_key", "key_id": "knh_kid_..." }
}
}post/api/v1/bots/{bot_id}/train
Start a training job for a bot. Requires train permission. The training_config fields shown below are optional overrides. When both model_slugs and model_sizes are omitted, the default medium model is trained. Pass a non-empty model list to select another available model.
request body
{
"dataset_id": "uuid",
"training_config": {
"epochs": 3,
"learning_rate": 0.0002
}
}response
{
"success": true,
"data": {
"bot_id": "uuid",
"jobs": [
{ "id": "uuid", "model_size": "medium", "status": "queued" }
],
"auth": { "method": "api_key", "key_id": "knh_kid_..." }
}
}04
Permissions reference
| Permission | Grants access to |
|---|---|
crawl | POST /api/v1/pages/{page_id}/recrawl |
dataset | POST /api/v1/sites/{site_id}/datasets |
train | POST /api/v1/bots/{bot_id}/train |
* | All of the above |
A key with crawl permission cannot start training jobs. Requests to unpermitted endpoints return 403 Forbidden.
05
Rate limits & quotas
| Limit | Value |
|---|---|
| Requests per minute (per key) | 60 |
| Requests per minute (per team) | 120 across API keys |
| Monthly page scrapes | Based on your subscription tier |
| Monthly trains | Based on your subscription tier |
| HTTP status | Meaning |
|---|---|
401 | Missing or invalid API key / JWT |
403 | Key lacks required permission, or resource belongs to another team |
404 | Resource not found |
429 | Rate limit exceeded (60 req/min per key or 120 req/min per team) |
Rate-limited requests return 429 Too Many Requests when either the per-key or team aggregate limit is reached. Quota, plan, and business-rule failures may return 200 with "success": false and an error message describing the failure. Check your current usage in Dashboard → Billing.
06
Error Handling
Successful responses and business-rule failures commonly use the same JSON envelope. Authentication, authorization, rate-limit, not-found, and server failures may instead return a plain HTTP error status.
error response
{
"success": false,
"data": null,
"error": "Page scrape limit reached (100/100 this month)"
}07
Automate the full pipeline
With a single API key scoped to *, you can automate the entire crawl → dataset → train pipeline.
pipeline.sh
API_KEY="knh_sec_your_secret"
BASE="https://api.kanha.ai"
# 1. Re-crawl a page
curl -X POST "$BASE/api/v1/pages/$PAGE_ID/recrawl" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"render_js": false}'
# 2. Generate dataset from site
curl -X POST "$BASE/api/v1/sites/$SITE_ID/datasets" \
-H "X-API-Key: $API_KEY"
# 3. Start training
curl -X POST "$BASE/api/v1/bots/$BOT_ID/train" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"dataset_id": "DATASET_ID"}'Tip
queued status. Dataset generation completes synchronously. Use the dashboard, or check training status via GET /api/training/status/{bot_id} (authenticated), to monitor progress.08
Key management
| Action | Behaviour |
|---|---|
| Revoke | Revoke a key instantly from the dashboard. Revoked keys stop working immediately. |
| Last used | A last-used timestamp is tracked per key, so you can identify unused keys. |
| Expiring keys | Expiring keys automatically stop working after their expiration date. No manual cleanup is needed. |
| Team scope | Keys are scoped to your team. Team members with Developer or Admin roles can create and revoke keys. |
