---
title: "Create a draft policy version with new check values"
method: PATCH
path: "/api/policy_version/draft/check"
tags: ["Policy Versions"]
---

# Create a draft policy version with new check values

`PATCH /api/policy_version/draft/check`

## Request

- Base URL: `https://app.herondata.io`
- URL: `https://app.herondata.io/api/policy_version/draft/check`
- Auth: API key in header `x-api-key`

Create a new draft from the active version with the check values you send. The live version can't be edited. Identify each check by its heron_id (from GET /policy_version/{version}). If a draft already exists, it is archived and its edits are not carried over. Checks you don't name keep their active values. All updates are validated first; if any fails, nothing is saved and the call returns 422 with every error listed. This does not publish the draft: call POST /policy_version/publish to make it live.

## Query parameters

- `user_id` integer

## Request body

- CheckValuesUpdateSchema
  - `change_description` string, nullable
  - `updates` CheckValueUpdate[], required
    - `check_heron_id` string, required: The check to update
    - `value` unknown, required

## Response `200`

OK. `changed` is false when every value already matches the active version; then no draft is created and any existing draft is left as it is.

- object
  - `changed` boolean
  - `policy_version` PolicyVersionSchema
    - `author_email` string: Email of whoever last acted on this version: the drafter while it is a draft, the publisher once published
    - `backtest_status` PolicyVersionBacktestStatus
      - `backtest_heron_id` string, nullable
      - `deal_count` integer, nullable: Deals the backtest covered
      - `finished_at` string, date-time, nullable
      - `flipped_deal_count` integer, nullable: Deals whose outcome changed, null unless the run completed
      - `run_status` unknown
      - `stale` boolean: The version was edited after that backtest was asked for, so re-run before publishing
    - `change_description` string, nullable: What changed in this version
    - `created` string, date-time
    - `last_edited_at` string, date-time, nullable
    - `policy_definition` PolicyDefinition
      - `policy_sections` PolicyVersionSection[], required
        - `branches` PolicyBranch[]: Ordered routes through the section; the section's own checks run on every route
          - `checks` Check[]
            - `attribute_description` string, nullable: What the attribute measures. Present only for accounts on policy versions
            - `attribute_display_name` string, nullable: The attribute's human-readable name. Present only for accounts on policy versions
            - `attribute_label` string, nullable
            - `attribute_unit` unknown
            - `attribute_validators` object[], nullable: The validity operators `attribute_label` offers, as in the catalogue's `check_options[].validators`, so a saved `is_valid` / `is_invalid` check can be worded. Empty for a check without an attribute or an attribute with no validity rule
              - …
            - `attribute_value_set` unknown
            - `boolean_check` BooleanCheck
              - …
            - `composite_check` CompositeCheck
              - …
            - `date_check` DateCheck
              - …
            - `date_delta_to_now_check` DateDeltaToNowCheck
              - …
            - `enhanced_sql_check` EnhancedSQLCheck
              - …
            - `group` string, nullable
            - `heron_id` string, nullable: Stable across edits; omit for a new check and one is minted. Policy versions only
            - `identity` string, nullable: Stable kind:key identity used to match stored check evaluations
            - `name` string, nullable
            - `numeric_check` NumericCheck
              - …
            - `parameters` object, nullable
            - `sql_check` SQLCheck
              - …
            - `string_check` StringCheck
              - …
          - `condition` Check, required
            - `attribute_description` string, nullable: What the attribute measures. Present only for accounts on policy versions
            - `attribute_display_name` string, nullable: The attribute's human-readable name. Present only for accounts on policy versions
            - `attribute_label` string, nullable
            - `attribute_unit` unknown
            - `attribute_validators` object[], nullable: The validity operators `attribute_label` offers, as in the catalogue's `check_options[].validators`, so a saved `is_valid` / `is_invalid` check can be worded. Empty for a check without an attribute or an attribute with no validity rule
              - …
            - `attribute_value_set` unknown
            - `boolean_check` BooleanCheck
              - …
            - `composite_check` CompositeCheck
              - …
            - `date_check` DateCheck
              - …
            - `date_delta_to_now_check` DateDeltaToNowCheck
              - …
            - `enhanced_sql_check` EnhancedSQLCheck
              - …
            - `group` string, nullable
            - `heron_id` string, nullable: Stable across edits; omit for a new check and one is minted. Policy versions only
            - `identity` string, nullable: Stable kind:key identity used to match stored check evaluations
            - `name` string, nullable
            - `numeric_check` NumericCheck
              - …
            - `parameters` object, nullable
            - `sql_check` SQLCheck
              - …
            - `string_check` StringCheck
              - …
          - `heron_id` string, nullable: Stable across renames; omit for a new branch and one is minted
          - `name` string, required
        - `checks` Check[]
          - `attribute_description` string, nullable: What the attribute measures. Present only for accounts on policy versions
          - `attribute_display_name` string, nullable: The attribute's human-readable name. Present only for accounts on policy versions
          - `attribute_label` string, nullable
          - `attribute_unit` unknown
          - `attribute_validators` object[], nullable: The validity operators `attribute_label` offers, as in the catalogue's `check_options[].validators`, so a saved `is_valid` / `is_invalid` check can be worded. Empty for a check without an attribute or an attribute with no validity rule
          - `attribute_value_set` unknown
          - `boolean_check` BooleanCheck
            - `auto_decline` boolean
            - `decline_code` string, nullable: The CRM's identifier for this decline reason, e.g. a LendSaas reason id. Left unset, the CRM sync falls back to this check's decline_description.
            - `decline_description` string, nullable
            - `email_template_name` string, nullable
            - `ignore_metric_availability` boolean
            - `is_mandatory` boolean
            - `on_failure` 'fail' | 'review_required'
            - `on_missing` 'missing_data' | 'fail' | 'pass': What the check reports when it would report missing data: `missing_data` (the default), `fail` or `pass`. A check saved with an older flag (`pass_if_value_missing` on a date-delta check) reads as the setting it stands for. With `ignore_metric_availability` or `pass_if_value_missing` set, only that setting is accepted
            - `pass_description` string, nullable
            - `transaction_scope` TransactionScope
              - …
            - `value` boolean
          - `composite_check` CompositeCheck
            - `auto_decline` boolean
            - `checks` Check[]
            - `decline_code` string, nullable: The CRM's identifier for this decline reason, e.g. a LendSaas reason id. Left unset, the CRM sync falls back to this check's decline_description.
            - `decline_description` string, nullable
            - `email_template_name` string, nullable
            - `ignore_metric_availability` boolean
            - `is_mandatory` boolean
            - `max_failing` integer, nullable
            - `on_failure` 'fail' | 'review_required'
            - `on_missing` 'missing_data' | 'fail' | 'pass': What the check reports when it would report missing data: `missing_data` (the default), `fail` or `pass`. A check saved with an older flag (`pass_if_value_missing` on a date-delta check) reads as the setting it stands for. With `ignore_metric_availability` or `pass_if_value_missing` set, only that setting is accepted
            - `pass_description` string, nullable
            - `transaction_scope` TransactionScope
              - …
            - `type` 'AND' | 'OR' | 'AT_MOST_FAILING'
          - `date_check` DateCheck
            - `auto_decline` boolean
            - `decline_code` string, nullable: The CRM's identifier for this decline reason, e.g. a LendSaas reason id. Left unset, the CRM sync falls back to this check's decline_description.
            - `decline_description` string, nullable
            - `email_template_name` string, nullable
            - `ignore_metric_availability` boolean
            - `is_mandatory` boolean
            - `on_failure` 'fail' | 'review_required'
            - `on_missing` 'missing_data' | 'fail' | 'pass': What the check reports when it would report missing data: `missing_data` (the default), `fail` or `pass`. A check saved with an older flag (`pass_if_value_missing` on a date-delta check) reads as the setting it stands for. With `ignore_metric_availability` or `pass_if_value_missing` set, only that setting is accepted
            - `pass_description` string, nullable
            - `transaction_scope` TransactionScope
              - …
            - `type` 'equal' | 'not_equal' | 'before' | 'before_or_on' | 'after' | 'after_or_on'
            - `value` string, date, nullable
          - `date_delta_to_now_check` DateDeltaToNowCheck
            - `auto_decline` boolean
            - `decline_code` string, nullable: The CRM's identifier for this decline reason, e.g. a LendSaas reason id. Left unset, the CRM sync falls back to this check's decline_description.
            - `decline_description` string, nullable
            - `email_template_name` string, nullable
            - `ignore_metric_availability` boolean
            - `is_mandatory` boolean
            - `on_failure` 'fail' | 'review_required'
            - `on_missing` 'missing_data' | 'fail' | 'pass': What the check reports when it would report missing data: `missing_data` (the default), `fail` or `pass`. A check saved with an older flag (`pass_if_value_missing` on a date-delta check) reads as the setting it stands for. With `ignore_metric_availability` or `pass_if_value_missing` set, only that setting is accepted
            - `pass_description` string, nullable
            - `pass_if_value_missing` boolean
            - `transaction_scope` TransactionScope
              - …
            - `type` 'greater_than' | 'greater_than_or_equal' | 'less_than' | 'less_than_or_equal'
            - `value` object, nullable
          - `enhanced_sql_check` EnhancedSQLCheck
            - `auto_decline` boolean
            - `check_type` 'equal' | 'not_equal' | 'greater_than' | 'greater_than_or_equal' | 'less_than' | 'less_than_or_equal' | 'before' | 'before_or_on' | 'after' | 'after_or_on' | 'is_in' | 'is_not_in', required
            - `column_name` string, required
            - `comparison_value` unknown, required
            - `data_type` 'numeric' | 'date' | 'string', required
            - `decline_code` string, nullable: The CRM's identifier for this decline reason, e.g. a LendSaas reason id. Left unset, the CRM sync falls back to this check's decline_description.
            - `decline_description` string, nullable
            - `email_template_name` string, nullable
            - `ignore_metric_availability` boolean
            - `is_mandatory` boolean
            - `on_failure` 'fail' | 'review_required'
            - `on_missing` 'missing_data' | 'fail' | 'pass': What the check reports when it would report missing data: `missing_data` (the default), `fail` or `pass`. A check saved with an older flag (`pass_if_value_missing` on a date-delta check) reads as the setting it stands for. With `ignore_metric_availability` or `pass_if_value_missing` set, only that setting is accepted
            - `pass_description` string, nullable
            - `query_name` string, required
            - `transaction_scope` TransactionScope
              - …
          - `group` string, nullable
          - `heron_id` string, nullable: Stable across edits; omit for a new check and one is minted. Policy versions only
          - `identity` string, nullable: Stable kind:key identity used to match stored check evaluations
          - `name` string, nullable
          - `numeric_check` NumericCheck
            - `auto_decline` boolean
            - `decline_code` string, nullable: The CRM's identifier for this decline reason, e.g. a LendSaas reason id. Left unset, the CRM sync falls back to this check's decline_description.
            - `decline_description` string, nullable
            - `email_template_name` string, nullable
            - `ignore_metric_availability` boolean
            - `is_mandatory` boolean
            - `on_failure` 'fail' | 'review_required'
            - `on_missing` 'missing_data' | 'fail' | 'pass': What the check reports when it would report missing data: `missing_data` (the default), `fail` or `pass`. A check saved with an older flag (`pass_if_value_missing` on a date-delta check) reads as the setting it stands for. With `ignore_metric_availability` or `pass_if_value_missing` set, only that setting is accepted
            - `pass_description` string, nullable
            - `transaction_scope` TransactionScope
              - …
            - `type` 'equal' | 'not_equal' | 'greater_than' | 'greater_than_or_equal' | 'less_than' | 'less_than_or_equal'
            - `value` union: The threshold: a number as a string, {"variable": {...}} to compare with another variable (with an optional "factor" that scales it), or {"lookup": {"table_heron_id", "column_id"}} to read it from a lookup table column
              - …
          - `parameters` object, nullable
          - `sql_check` SQLCheck
            - `auto_decline` boolean
            - `column_name` string, required
            - `decline_code` string, nullable: The CRM's identifier for this decline reason, e.g. a LendSaas reason id. Left unset, the CRM sync falls back to this check's decline_description.
            - `decline_description` string, nullable
            - `email_template_name` string, nullable
            - `ignore_metric_availability` boolean
            - `is_mandatory` boolean
            - `on_failure` 'fail' | 'review_required'
            - `on_missing` 'missing_data' | 'fail' | 'pass': What the check reports when it would report missing data: `missing_data` (the default), `fail` or `pass`. A check saved with an older flag (`pass_if_value_missing` on a date-delta check) reads as the setting it stands for. With `ignore_metric_availability` or `pass_if_value_missing` set, only that setting is accepted
            - `pass_description` string, nullable
            - `query_name` string, required
            - `transaction_scope` TransactionScope
              - …
          - `string_check` StringCheck
            - `auto_decline` boolean
            - `decline_code` string, nullable: The CRM's identifier for this decline reason, e.g. a LendSaas reason id. Left unset, the CRM sync falls back to this check's decline_description.
            - `decline_description` string, nullable
            - `email_template_name` string, nullable
            - `ignore_metric_availability` boolean
            - `is_mandatory` boolean
            - `match_count` integer, nullable
            - `on_failure` 'fail' | 'review_required'
            - `on_missing` 'missing_data' | 'fail' | 'pass': What the check reports when it would report missing data: `missing_data` (the default), `fail` or `pass`. A check saved with an older flag (`pass_if_value_missing` on a date-delta check) reads as the setting it stands for. With `ignore_metric_availability` or `pass_if_value_missing` set, only that setting is accepted
            - `pass_description` string, nullable
            - `transaction_scope` TransactionScope
              - …
            - `type` 'equal' | 'not_equal' | 'starts_with' | 'starts_with_any_of' | 'does_not_start_with_any_of' | 'contains' | 'does_not_start_with' | 'does_not_contain' | 'is_in' | 'is_not_in' | 'has_none_of' | 'has_any_of' | 'has_only' | 'has_fewer_than_n_matches' | 'has_more_than_n_matches' | 'is_valid' | 'is_invalid'
            - `value` union: The value as a string, or {"lookup": {"table_heron_id"}} for is_in, is_not_in, has_any_of, has_none_of or has_only to read the list from a lookup table's rows
              - …
        - `default_branch` DefaultPolicyBranch
          - `checks` Check[]
            - `attribute_description` string, nullable: What the attribute measures. Present only for accounts on policy versions
            - `attribute_display_name` string, nullable: The attribute's human-readable name. Present only for accounts on policy versions
            - `attribute_label` string, nullable
            - `attribute_unit` unknown
            - `attribute_validators` object[], nullable: The validity operators `attribute_label` offers, as in the catalogue's `check_options[].validators`, so a saved `is_valid` / `is_invalid` check can be worded. Empty for a check without an attribute or an attribute with no validity rule
              - …
            - `attribute_value_set` unknown
            - `boolean_check` BooleanCheck
              - …
            - `composite_check` CompositeCheck
              - …
            - `date_check` DateCheck
              - …
            - `date_delta_to_now_check` DateDeltaToNowCheck
              - …
            - `enhanced_sql_check` EnhancedSQLCheck
              - …
            - `group` string, nullable
            - `heron_id` string, nullable: Stable across edits; omit for a new check and one is minted. Policy versions only
            - `identity` string, nullable: Stable kind:key identity used to match stored check evaluations
            - `name` string, nullable
            - `numeric_check` NumericCheck
              - …
            - `parameters` object, nullable
            - `sql_check` SQLCheck
              - …
            - `string_check` StringCheck
              - …
          - `condition` unknown
          - `decline_code` string, nullable: Optional code sent with a failed or review_required result
          - `decline_description` string, nullable: Required when result is failed or review_required
          - `heron_id` string, nullable
          - `name` string
          - `result` unknown
        - `display_order` integer, nullable
        - `heron_id` string, nullable
        - `name` string, required
        - `use_case` 'background_check' | 'cashflow'
    - `published_at` string, date-time, nullable
    - `status` 'draft' | 'active' | 'archived'
    - `version` integer: Version number, unique per account

## Other responses

- `404`: No active policy version
- `422`: An update is invalid, or the policy versions changed concurrently. `errors` lists every problem with its path, a stable code and a message. Codes are check_not_found, unsupported_check_class, invalid_value and duplicate_check, plus the check's own validation codes (e.g. type_mismatch, out_of_range) when the new value breaks one of its rules.

## Changes

- **2026-11-03** `1ec936e17fef`: 4 warning
  - added the new `industry_category` enum value to the `policy_version/policy_definition/allOf[#/components/schemas/PolicyDefinition]/policy_sections/items/branches/items/checks/items/attribute_value_set` response property for the response status `200`
  - added the new `industry_category` enum value to the `policy_version/policy_definition/allOf[#/components/schemas/PolicyDefinition]/policy_sections/items/branches/items/condition/allOf[#/components/schemas/Check]/attribute_value_set` response property for the response status `200`
  - added the new `industry_category` enum value to the `policy_version/policy_definition/allOf[#/components/schemas/PolicyDefinition]/policy_sections/items/checks/items/attribute_value_set` response property for the response status `200`
  - added the new `industry_category` enum value to the `policy_version/policy_definition/allOf[#/components/schemas/PolicyDefinition]/policy_sections/items/default_branch/allOf[#/components/schemas/DefaultPolicyBranch]/checks/items/attribute_value_set` response property for the response status `200`
- **2026-11-03** `bd8008e49534`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/herondata/apis/heron-data-api/changes/api/policy_version/draft/check/patch.md)

---

[API](https://skmtc.dev/herondata/apis/heron-data-api.md) - [All operations](https://skmtc.dev/herondata/apis/heron-data-api/llms.txt) - [OpenAPI document](https://skmtc.dev/herondata/apis/heron-data-api/revisions/4f9eaaa87f09?raw)
