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

# Update test case

> Update a case name, local criteria, shared groups or test setup.

Update a case name, local criteria, shared groups or test setup.

`name` is required even when changing only setup or criteria. Omitted optional fields are preserved. A captured conversation cannot be changed into a scenario. Saving does not change previous run snapshots.

## Headers

<ParamField header="Authorization" type="string" required>
  Bearer token containing your workspace API key. The key needs `write` scope.
</ParamField>

## Path parameters

<ParamField path="id" type="string" required>
  Case UUID.
</ParamField>

## Body parameters

<ParamField body="name" type="string" required>
  Nonblank name, up to 200 characters.
</ParamField>

<ParamField body="criteria" type="array">
  Local criterion definitions, up to 50. Omit to preserve criteria on update; an empty array removes local criteria.
</ParamField>

<ParamField body="criteriaGroupIds" type="array">
  Shared group UUIDs, up to 50. Overrides `criteriaGroupId`; an empty array detaches all groups.
</ParamField>

<ParamField body="criteriaGroupId" type="string">
  Single-group compatibility field. On update, `null` detaches all groups if `criteriaGroupIds` is omitted.
</ParamField>

<ParamField body="attributeOverrides" type="object">
  Attribute values for this test only, up to 100 KB. Reserved top-level names `__proto__`, `constructor` and `prototype` are rejected.
</ParamField>

<ParamField body="scenario" type="object">
  Scripted scenario input. See [Case input](/en/api-reference/test-suite#case-input). Only scripted cases can update this field.
</ParamField>

<ParamField body="actionResponses" type="array">
  Captured-conversation response overrides, up to 200. See [Recorded Action overrides](/en/api-reference/test-suite#recorded-action-overrides).
</ParamField>

<ParamField body="artifacts" type="array">
  Up to 100 manual references: `kind` is `rule` or `article`, and `id` is a UUID. Rules must be assigned to the agent; articles must be live workspace articles.
</ParamField>

## Response

Returns the updated case detail. The example intentionally shows empty arrays for Action-response overrides and run history.

<RequestExample>
  ```bash cURL theme={null}
  curl --request PATCH \
    --url 'https://api-prod.usefini.com/v2/test-suite/cases/00000000-0000-4000-8000-000000000002/public' \
    --header 'Authorization: Bearer fini_your_api_key' \
    --header 'Content-Type: application/json' \
    --data '{
    "name": "Refund policy",
    "criteria": [
      {
        "name": "No handoff",
        "type": "deterministic",
        "condition": {
          "scope": "SCALAR",
          "predicate": {
            "left": {
              "path": "escalated",
              "dataType": "boolean"
            },
            "operator": "==",
            "right": {
              "value": false
            }
          }
        },
        "blocking": true
      }
    ]
  }'
  ```

  ```javascript Node.js theme={null}
  const body = {
    "name": "Refund policy",
    "criteria": [
      {
        "name": "No handoff",
        "type": "deterministic",
        "condition": {
          "scope": "SCALAR",
          "predicate": {
            "left": {
              "path": "escalated",
              "dataType": "boolean"
            },
            "operator": "==",
            "right": {
              "value": false
            }
          }
        },
        "blocking": true
      }
    ]
  };

  const response = await fetch("https://api-prod.usefini.com/v2/test-suite/cases/00000000-0000-4000-8000-000000000002/public", {
    method: "PATCH",
    headers: {
      Authorization: "Bearer fini_your_api_key",
      "Content-Type": "application/json",
    },
    body: JSON.stringify(body),
  });
  if (!response.ok) throw new Error(await response.text());
  const result = await response.json();
  ```

  ```python Python theme={null}
  import requests
  import json

  body = json.loads('''
  {
    "name": "Refund policy",
    "criteria": [
      {
        "name": "No handoff",
        "type": "deterministic",
        "condition": {
          "scope": "SCALAR",
          "predicate": {
            "left": {
              "path": "escalated",
              "dataType": "boolean"
            },
            "operator": "==",
            "right": {
              "value": false
            }
          }
        },
        "blocking": true
      }
    ]
  }
  ''')

  response = requests.request(
      "PATCH",
      "https://api-prod.usefini.com/v2/test-suite/cases/00000000-0000-4000-8000-000000000002/public",
      headers={"Authorization": "Bearer fini_your_api_key"},
      json=body,
  )
  response.raise_for_status()
  result = response.json()
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "id": "00000000-0000-4000-8000-000000000002",
    "companyId": "00000000-0000-4000-8000-000000000011",
    "botId": "00000000-0000-4000-8000-000000000001",
    "name": "Refund policy",
    "sourceType": "scenario",
    "sourceInteractionId": null,
    "criteria": [
      {
        "id": "2995012b-d9bf-58e9-c6c7-672205196681",
        "companyId": "00000000-0000-4000-8000-000000000011",
        "defaultCriterionId": null,
        "name": "No handoff",
        "type": "deterministic",
        "condition": {
          "scope": "SCALAR",
          "predicate": {"left": {"path": "escalated", "dataType": "boolean"}, "operator": "==", "right": {"value": false}}
        },
        "blocking": true,
        "judgePrompt": null,
        "passPrompt": null,
        "failPrompt": null,
        "isActive": true,
        "createdAt": "2026-10-12T10:00:00.000Z",
        "updatedAt": "2026-10-12T10:00:00.000Z"
      },
      {
        "id": "00000000-0000-4000-8000-000000000012",
        "companyId": "00000000-0000-4000-8000-000000000011",
        "defaultCriterionId": null,
        "name": "No handoff",
        "type": "deterministic",
        "condition": {
          "scope": "SCALAR",
          "predicate": {"left": {"path": "escalated", "dataType": "boolean"}, "operator": "==", "right": {"value": false}}
        },
        "blocking": true,
        "judgePrompt": null,
        "passPrompt": null,
        "failPrompt": null,
        "isActive": true,
        "createdAt": "2026-10-12T10:00:00.000Z",
        "updatedAt": "2026-10-12T10:00:00.000Z"
      }
    ],
    "artifacts": [{"kind": "rule", "id": "00000000-0000-4000-8000-000000000005", "name": "Refund workflow", "origin": "manual"}],
    "criteriaGroupId": "00000000-0000-4000-8000-000000000003",
    "criteriaGroupIds": ["00000000-0000-4000-8000-000000000003"],
    "criteriaGroup": {
      "id": "00000000-0000-4000-8000-000000000003",
      "companyId": "00000000-0000-4000-8000-000000000011",
      "botId": "00000000-0000-4000-8000-000000000001",
      "name": "Refund checks",
      "criteria": [
        {
          "id": "00000000-0000-4000-8000-000000000012",
          "companyId": "00000000-0000-4000-8000-000000000011",
          "defaultCriterionId": null,
          "name": "No handoff",
          "type": "deterministic",
          "condition": {
            "scope": "SCALAR",
            "predicate": {"left": {"path": "escalated", "dataType": "boolean"}, "operator": "==", "right": {"value": false}}
          },
          "blocking": true,
          "judgePrompt": null,
          "passPrompt": null,
          "failPrompt": null,
          "isActive": true,
          "createdAt": "2026-10-12T10:00:00.000Z",
          "updatedAt": "2026-10-12T10:00:00.000Z"
        }
      ],
      "revision": 1,
      "createdAt": "2026-10-12T10:00:00.000Z",
      "updatedAt": "2026-10-12T10:00:00.000Z"
    },
    "criteriaGroups": [
      {
        "id": "00000000-0000-4000-8000-000000000003",
        "companyId": "00000000-0000-4000-8000-000000000011",
        "botId": "00000000-0000-4000-8000-000000000001",
        "name": "Refund checks",
        "criteria": [
          {
            "id": "00000000-0000-4000-8000-000000000012",
            "companyId": "00000000-0000-4000-8000-000000000011",
            "defaultCriterionId": null,
            "name": "No handoff",
            "type": "deterministic",
            "condition": {
              "scope": "SCALAR",
              "predicate": {"left": {"path": "escalated", "dataType": "boolean"}, "operator": "==", "right": {"value": false}}
            },
            "blocking": true,
            "judgePrompt": null,
            "passPrompt": null,
            "failPrompt": null,
            "isActive": true,
            "createdAt": "2026-10-12T10:00:00.000Z",
            "updatedAt": "2026-10-12T10:00:00.000Z"
          }
        ],
        "revision": 1,
        "createdAt": "2026-10-12T10:00:00.000Z",
        "updatedAt": "2026-10-12T10:00:00.000Z"
      }
    ],
    "criterionOrigins": {
      "2995012b-d9bf-58e9-c6c7-672205196681": {"groupId": "00000000-0000-4000-8000-000000000003", "groupName": "Refund checks"}
    },
    "localCriteria": [
      {
        "id": "00000000-0000-4000-8000-000000000012",
        "companyId": "00000000-0000-4000-8000-000000000011",
        "defaultCriterionId": null,
        "name": "No handoff",
        "type": "deterministic",
        "condition": {
          "scope": "SCALAR",
          "predicate": {"left": {"path": "escalated", "dataType": "boolean"}, "operator": "==", "right": {"value": false}}
        },
        "blocking": true,
        "judgePrompt": null,
        "passPrompt": null,
        "failPrompt": null,
        "isActive": true,
        "createdAt": "2026-10-12T10:00:00.000Z",
        "updatedAt": "2026-10-12T10:00:00.000Z"
      }
    ],
    "createdAt": "2026-10-12T10:00:00.000Z",
    "updatedAt": "2026-10-12T10:00:00.000Z",
    "messages": [{"id": "00000000-0000-4000-8000-000000000010", "role": "user", "content": "Am I eligible for a refund?"}],
    "conversationName": "Refund policy",
    "attributeOverrides": {"plan": "standard"},
    "history": [],
    "latestIndividualRun": null,
    "actionResponses": [],
    "turns": [
      {
        "message": "Am I eligible for a refund?",
        "actions": [
          {
            "ruleId": "00000000-0000-4000-8000-000000000005",
            "nodeId": "lookup",
            "toolId": "00000000-0000-4000-8000-000000000006",
            "success": true,
            "output": {"eligible": true}
          }
        ]
      }
    ],
    "userAttributes": {"plan": "standard"},
    "createdBy": null,
    "deletedAt": null
  }
  ```
</ResponseExample>


## Related topics

- [Overview](/en/api-reference/test-suite.md)
- [Test Suite](/en/testing/test-suite.md)
- [Create test case](/en/api-reference/create-test-suite-case.md)


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