---
title: "Unapprove Factor"
method: POST
path: "/risk-assessment/factor-assessments/{factor_assessment_id}/unapprove"
tags: ["risk-assessment"]
---

# Unapprove Factor

`POST /risk-assessment/factor-assessments/{factor_assessment_id}/unapprove`

## Request

- Base URL: `https://api.kobaltlabs.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.kobaltlabs.com/risk-assessment/factor-assessments/{factor_assessment_id}/unapprove`
- Auth: none declared

Undo an approval and go back to `PROPOSED`.

Also clears attribution, mirroring `requirement_checks.py`'s
`/unapprove`. It does not touch `manual_inherent_risk_label` — undoing an
override is `PATCH .../{id}` with `manual_inherent_risk_label: null`, a
distinct action from undoing an approval.

## Path parameters

- `factor_assessment_id` string, uuid, required

## Response `200`

Successful Response

- FactorAssessmentSummary: One row of the run overview — no steps, no citations.
  - `factor_assessment_id` string, uuid, required
  - `risk_factor` FactorRef, required
    - `risk_factor_id` string, uuid, nullable, required
    - `slug` string, required
    - `name` string, required
  - `status` 'queued' | 'running' | 'complete' | 'error', required: Lifecycle of one factor's assessment within a run. There is no deferral state: a factor either produces a rating its rationale can defend, or it errors. Missing evidence is narrated in the rationale.
  - `progress_pct` integer, nullable, required
  - `current_activity` string, nullable, required
  - `suggested_rating` RatingOptionView, required: One level of the tenant's INHERENT_RISK_LEVEL scale. The scale is per-tenant and variable length, so the UI renders N cells from this list rather than assuming five. `position` is 1-based and derived from order, not from `order_index`, which may be sparse.
    - `option_id` string, uuid, required
    - `label` string, required
    - `position` integer, required
    - `hex_color` string, nullable, required
  - `manual_rating` RatingOptionView, required: One level of the tenant's INHERENT_RISK_LEVEL scale. The scale is per-tenant and variable length, so the UI renders N cells from this list rather than assuming five. `position` is 1-based and derived from order, not from `order_index`, which may be sparse.
    - `option_id` string, uuid, required
    - `label` string, required
    - `position` integer, required
    - `hex_color` string, nullable, required
  - `effective_rating` RatingOptionView, required: One level of the tenant's INHERENT_RISK_LEVEL scale. The scale is per-tenant and variable length, so the UI renders N cells from this list rather than assuming five. `position` is 1-based and derived from order, not from `order_index`, which may be sparse.
    - `option_id` string, uuid, required
    - `label` string, required
    - `position` integer, required
    - `hex_color` string, nullable, required
  - `review_state` 'proposed' | 'approved' | 'overridden', required: Where a human reviewer stands on the agent's proposed rating. Written by the approval workflow (M5); until then every completed factor sits at PROPOSED, which is what renders the "Kobalt proposed" chip.
  - `reviewer_name` string, nullable, required
  - `reviewed_at` string, date-time, nullable, required
  - `citation_count` integer, required
  - `distinct_document_count` integer, required
  - `step_count` integer, nullable, required
  - `duration_ms` integer, nullable, required
  - `error` string, nullable, required
  - `agent_run_id` string, uuid, nullable, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/kobaltlabs/apis/fastapi.md) - [All operations](https://skmtc.dev/kobaltlabs/apis/fastapi/llms.txt) - [OpenAPI document](https://skmtc.dev/kobaltlabs/apis/fastapi/revisions/8587332d5e43?raw)
