Kiwami

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).