> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kiwiflow.io/llms.txt
> Use this file to discover all available pages before exploring further.

# CI check reporting

> Assign a project-bound checker credential and submit observed results for the exact current candidate and Verify attempt.

Kiwi accepts named results from an existing CI pipeline over HTTP. It does not start a pipeline or inspect its logs. A project Admin issues a checker credential restricted to selected check IDs and an expiry. Store the one-time secret in the CI secret manager used by your team.

The checker API uses the origin of the exact MCP URL copied from the signed-in Kiwi setup helper. Keep its scheme, host, and any port; remove only the `/mcp` path and append `/v1/runs/{runId}/checks`. For example, if the copied MCP URL is `https://<host>:<port>/mcp`, the checker request URL is `https://<host>:<port>/v1/runs/{runId}/checks`. Do not guess a host or use Kiwi's website or documentation origin. This route is part of hosted Kiwi; customers do not deploy a separate service. MCP requests continue to use the full URL ending in `/mcp`.

## Assign the checker

The accepted Plan check must name the check ID, allow checker\_reported in permittedOrigins, and list the credential's nonsecret reporterId in authorizedReporterIds. The credential's allowed\_check\_ids must also contain that exact check ID.

Issue the credential in the project's **Connections** area. Its record id is not its reporterId. Store secret once in CI; the response reports secretAvailable as true only at initial issuance. A replay returns secret as null and does not create a replacement.

## Read current check context

Send the key as a Bearer token and read `GET /v1/runs/{runId}/checks` before each report. The response shows the current runVersion, acceptedPlanRevision, candidateRef, implementationAttemptId, verificationState, verificationAttemptId, and checks authorized for this key and accepted Plan.

| GET context field | POST body field |
| - | - |
| runVersion | expected\_run\_version |
| acceptedPlanRevision | plan\_revision |
| candidateRef | candidate\_ref |
| implementationAttemptId | implementation\_attempt\_id |
| verificationAttemptId | attempt\_id; when null and Verify is ready, generate the first verification attempt UUID. |
| checks\[].checkId | check\_id |

Generate a fresh UUID for command\_id for each new report. Read runVersion immediately before POST and use that positive value as expected\_run\_version.

Do not report if candidateRef or implementationAttemptId is null, or the verification state is not ready for a result. Use the current values from that response; never use a version or candidate cached from an earlier pipeline run.

## Submit an observed result

`POST /v1/runs/{runId}/checks` uses snake\_case HTTP fields. Replace placeholders with values from the context response. The numeric values below are examples, not current state. If verificationAttemptId is null while Verify is ready, create one UUID for attempt\_id; on subsequent reports, use the attempt ID returned by the next context read.

```json theme={null}
{
  "command_id": "00000000-0000-4000-8000-000000000003",
  "expected_run_version": 2,
  "attempt_id": "00000000-0000-4000-8000-000000000004",
  "check_id": "help-search-results",
  "status": "pass",
  "candidate_ref": "commit:REPLACE_WITH_CURRENT_CANDIDATE",
  "plan_revision": 1,
  "implementation_attempt_id": "00000000-0000-4000-8000-000000000005",
  "evidence": {
    "summary": "The no-results message and revise-search action appear, and matching articles remain visible.",
    "url": "https://ci.example.org/runs/REPLACE_WITH_ACTUAL_RUN"
  }
}
```

Allowed statuses are pass, fail, blocked, and not-applicable. Only pass can satisfy the required-check gate. fail fails Verify; blocked and not-applicable block it. A required result cannot be cleared by reporting not-applicable.

The checker POST response includes a command receipt and refreshed check context. A receipt confirms recording, not acceptance of the Verify gate. Every required check must report pass for the current Plan revision, implementation attempt, candidate, and verification attempt before Verify advances.

## Resolve a lost response

If a check POST may have reached Kiwi but its response is unknown, retry the exact body with the same command\_id. After a definitive stale version or attempt response, read the current context and submit a new command ID with the current version and attempt. Do not reuse an ID with changed content.

If a credential issuance has an unresolved status, check the credential record in Kiwi before issuing another. An issuance replay does not reveal a lost secret or create a replacement. See [Retries and recovery](https://docs.kiwiflow.io/retries-and-recovery.md) and the [Integration API reference](https://docs.kiwiflow.io/api-reference.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.