Findings API
The Findings API exposes Finding clusters, diagnostic settings, built-in Rules, on-demand analysis Runs, time-window backfills, and provider-neutral repair work items.
Base URL:
https://api.provon.dev/v1Project API keys need diagnostics:read for read routes and diagnostics:write for mutation
routes. Signed-in Workbench sessions can use the same project-qualified routes when the user has
the corresponding project permission.
Findings#
| Method | Path | Purpose |
|---|---|---|
GET |
/projects/:projectId/diagnostics/findings |
List Finding clusters |
GET |
/projects/:projectId/diagnostics/findings/:findingId |
Read one Finding and its primary work item |
PATCH |
/projects/:projectId/diagnostics/findings/:findingId |
Update review or resolution state |
POST |
/projects/:projectId/diagnostics/findings/discover |
Analyze the latest conversation activity snapshot |
GET |
/projects/:projectId/diagnostics/findings/:findingId/work-items |
List work items for a Finding |
GET |
/projects/:projectId/diagnostics/findings/:findingId/work-items/:workItemId |
Read one work item |
POST |
/projects/:projectId/diagnostics/findings/:findingId/work-items |
Create and confirm a repair handoff |
List query parameters:
| Parameter | Type | Notes |
|---|---|---|
reviewStatus |
unreviewed, confirmed, or dismissed |
Optional filter |
resolutionStatus |
unresolved, awaiting_verification, resolved, regressed |
Optional filter |
severity |
critical, high, medium, low, info |
Optional filter |
minDiagnosticScore |
number from 0 to 1 |
Optional filter |
lastDetectedAfter |
Unix milliseconds | Inclusive lower bound |
lastDetectedBefore |
Unix milliseconds | Exclusive upper bound |
limit |
integer from 1 to 500 |
Page size |
cursor |
opaque string | Cursor from prior result |
lastDetectedAfter must be earlier than lastDetectedBefore.
List responses include findings, each with its primary workItem, plus pagination.limit and
pagination.nextCursor.
Read a Finding#
GET /v1/projects/:projectId/diagnostics/findings/:findingIdResponse:
{
"id": "fnd_...",
"clusterFingerprint": "...",
"fingerprintVersion": "finding-cluster-v1",
"reviewStatus": "unreviewed",
"resolutionStatus": "unresolved",
"severity": "high",
"diagnosticScore": 0.85,
"diagnosticConfidence": 0.82,
"title": "Required verification was skipped",
"summary": "The agent claimed completion without running the required verification.",
"causeAssessment": "The first uncorrected fault is the omitted verification step.",
"remediationHint": "Run and report the required verification before claiming completion.",
"metadata": {
"categoryKey": "goal_not_verified",
"diagnosticRule": {
"ruleId": "rule_...",
"ruleKey": "task-fulfillment"
}
},
"firstDetectedAt": 1760000000000,
"lastDetectedAt": 1760000000000,
"conversationId": "conv_123",
"diagnosticAnchor": {
"conversationId": "conv_123",
"traceId": "trace_123",
"spanId": "span_123",
"stepIndex": 8,
"quotes": [{ "quote": "I have completed the task." }]
},
"evidence": [
{
"ref": "span_123",
"kind": "span",
"title": "verify-answer",
"summary": "Verification span was never executed.",
"url": null,
"location": {
"traceId": "trace_123",
"spanId": "span_123",
"stepIndex": 8,
"quotes": [{ "quote": "I have completed the task." }]
}
}
],
"evidenceWindow": {
"startMs": 1760000000000,
"endMs": 1760000100000,
"conversationIds": ["conv_123"]
},
"analysisRevision": "drv_...",
"evidenceSnapshotRevision": "cesr_...",
"evidenceThroughMs": 1760000100000,
"createdAt": 1760000200000,
"updatedAt": 1760000200000,
"reviewedAt": null,
"resolvedAt": null,
"regressedAt": null,
"workItem": null
}Update review or resolution#
Supported PATCH fields (send one at a time):
{
"reviewStatus": "confirmed"
}{
"resolutionStatus": "resolved"
}reviewStatus can be unreviewed, confirmed, or dismissed. Manual resolution uses
resolutionStatus: "resolved" | "unresolved". Dismissal atomically clears resolution state.
reviewStatus and resolutionStatus cannot be updated in the same request.
A Finding with an active work item (provisioning, planned, or in_progress) cannot be
dismissed or manually resolved. The API returns 409 ACTIVE_WORK_ITEM or 409 WORK_ITEM_NOT_DONE.
Discover latest Findings#
Queue diagnostic discovery for the latest activity snapshot of one conversation:
POST /v1/projects/:projectId/diagnostics/findings/discoverResponse:
{
"conversationId": "conv_123",
"outcome": "findings_found",
"findings": []
}outcome is findings_found or no_findings. This endpoint is synchronous: it analyzes the
latest conversation snapshot and returns the produced Findings directly. It is not a backfill.
Work Items#
Work-item creation accepts provider: "github" | "gitlab" | "linear" | "jira" and an optional
provider destination object. The configured connector default is used when destination is omitted.
POST /v1/projects/:projectId/diagnostics/findings/:findingId/work-items{
"provider": "github",
"destination": {
"owner": "provon",
"repo": "provon"
}
}Lifecycle actions:
POST .../work-items/:workItemId/sync
POST .../work-items/:workItemId/retry
POST .../work-items/:workItemId/replacements
POST .../work-items/:workItemId/abandon- Retry only works for a failed provisioning attempt (
status: provisioning,externalId: null,syncState: error). - Replace creates a new work item in another provider and accepts the same provider and destination body as creation.
- Abandon only detaches the local handoff; it does not close the external issue.
- Sync returns
{ outcome, finding }.outcomecan beupdated,unchanged,failed,not_syncable, ornot_current.
Settings#
| Method | Path | Purpose |
|---|---|---|
GET |
/projects/:projectId/diagnostics/settings |
Read automatic scheduling settings |
PATCH |
/projects/:projectId/diagnostics/settings |
Enable or disable automatic scheduling |
Patch body:
{
"automaticSchedulingEnabled": true
}Rules#
| Method | Path | Purpose |
|---|---|---|
GET |
/projects/:projectId/diagnostics/rules |
List built-in Rules and configuration |
GET |
/projects/:projectId/diagnostics/rules/:ruleId |
Read one Rule |
PATCH |
/projects/:projectId/diagnostics/rules/:ruleId |
Enable/disable or reconfigure one Rule |
POST |
/projects/:projectId/diagnostics/rules/:ruleId/backfill-requests |
Queue a time-window backfill |
Patch either enabled:
{
"enabled": false
}or configuration:
{
"configuration": {
"keywords": ["checkout", "payment"],
"minSignalScore": 0.25,
"minDiagnosticConfidence": 0.5,
"adjudicationMode": "auto",
"adjudicationModel": null,
"signalOverrides": {
"runtime_error": { "enabled": true, "severity": "high" }
}
}
}adjudicationMode can be auto or deterministic-only. Signal override severities can be
critical, high, medium, low, or info.
Backfill body:
{
"startMs": 1760000000000,
"endMs": 1760086400000,
"maxConversations": 100
}Backfill responses use 202 when Runs are queued. Include an Idempotency-Key header to avoid
duplicate backfills for the same rule and window. The default maxConversations is 10,000 and the
maximum is 100,000.
On-Demand Runs#
Queue enabled Rules for one conversation activity snapshot:
POST /v1/projects/:projectId/diagnostics/analysis-runs{
"conversationId": "conv_123",
"lastActivityAt": 1760000000000,
"traceIds": ["trace_123"]
}conversationId and lastActivityAt are required. traceIds is optional and is filtered to
string values. Response:
{
"enabledRules": 5,
"runsCreated": 1
}Common Errors#
| HTTP | Code | When |
|---|---|---|
400 |
INVALID_FILTER |
Unsupported enum value, malformed cursor, or lastDetectedAfter >= lastDetectedBefore. |
404 |
FINDING_NOT_FOUND |
Finding or referenced work item does not exist. |
404 |
DIAGNOSTIC_RULE_NOT_FOUND |
Rule does not exist. |
404 |
DISCOVERY_CONVERSATION_NOT_FOUND |
No recent conversation found for discovery. |
409 |
DISCOVERY_CONVERSATION_NOT_READY |
Latest conversation is not ready for analysis. |
409 |
ACTIVE_WORK_ITEM |
Cannot dismiss a Finding with an active work item. |
409 |
WORK_ITEM_NOT_DONE |
Cannot resolve a Finding whose work item is not done. |
409 |
WORK_ITEM_ALREADY_EXISTS |
A primary work item already exists for this Finding. |
409 |
WORK_ITEM_NOT_CURRENT |
The work item was replaced or is no longer primary. |
409 |
WORK_ITEM_NOT_RETRYABLE |
The work item is not a failed provisioning attempt. |
409 |
FINDING_DISMISSED |
Cannot create a work item for a dismissed Finding. |
503 |
WORK_ITEM_PROVIDER_UNAVAILABLE |
Connector is missing, disabled, or default destination is unset. |
503 |
DIAGNOSTIC_RULES_UNAVAILABLE |
Diagnostic rule service is not mounted in this deployment. |
503 |
FINDING_WORK_ITEMS_UNAVAILABLE |
Work item service is not mounted in this deployment. |