API reference
A minimal REST API for scripting what the dashboard otherwise does by hand: listing your projects, and triggering and checking on runs.
Authentication
Create a token from your organization's API tokens page (linked from your dashboard, if you can manage integrations). The raw token is shown exactly once, at creation — copy it immediately, since only its hash is ever stored afterward.
Send it as a bearer token on every request:
curl -H "Authorization: Bearer kiw_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
https://your-kiwami-host/api/v1/projects
A missing or invalid token returns 401:
{"error": "invalid or missing API token"}
Scope
A token is not scoped per-project or read-only — it can see every project in its organization and trigger a run on any of its suites, the same authority an ordinary member already has. Per-token scoping (a read-only token, one scoped to a single project) is real future work, not built yet — treat a token the same way you'd treat a password with run access.
GET /api/v1/projects
Every project in the token's organization.
curl -H "Authorization: Bearer $TOKEN" https://your-kiwami-host/api/v1/projects
{
"projects": [
{
"id": 7,
"name": "Checkout E2E",
"slug": "checkout-e2e",
"framework": "playwright",
"repo_url": "https://github.com/acme/checkout.git",
"default_branch": "main"
}
]
}
GET /api/v1/projects/<id>
One project, plus its suites.
curl -H "Authorization: Bearer $TOKEN" https://your-kiwami-host/api/v1/projects/7
{
"id": 7,
"name": "Checkout E2E",
"slug": "checkout-e2e",
"framework": "playwright",
"repo_url": "https://github.com/acme/checkout.git",
"default_branch": "main",
"suites": [
{"id": 12, "name": "checkout flow", "slug": "checkout-flow", "framework": "playwright"}
]
}
A project outside the token's organization — or one that doesn't exist —
returns 404.
POST /api/v1/suites/<id>/runs
Triggers a run for one suite, exactly like clicking Run on its project page. Takes no body.
curl -X POST -H "Authorization: Bearer $TOKEN" \
https://your-kiwami-host/api/v1/suites/12/runs
{
"id": 104,
"suite_id": 12,
"status": "pending",
"exit_code": null,
"created_at": "2026-10-12T20:41:00Z",
"started_at": null,
"finished_at": null,
"test_results": []
}
Returns 201 on success, 404 if the suite doesn't exist in the token's
organization.
GET /api/v1/runs/<id>
A run's current status, with per-test results once the framework's report has been parsed (see Reading results).
curl -H "Authorization: Bearer $TOKEN" https://your-kiwami-host/api/v1/runs/104
{
"id": 104,
"suite_id": 12,
"status": "passed",
"exit_code": 0,
"created_at": "2026-10-12T20:41:00Z",
"started_at": "2026-10-12T20:41:02Z",
"finished_at": "2026-10-12T20:41:48Z",
"test_results": [
{"name": "can add an item to the cart", "status": "passed"},
{"name": "can complete checkout", "status": "passed"}
]
}
Polling this endpoint after triggering a run is the usual pattern for a
CI pipeline that wants to wait on the result: run exists in pending or
running until it reaches a terminal status (passed, failed, or
errored).