# Test condition

Evaluates the automation's condition once, against the given event when one is supplied or against its retained source data otherwise. Nothing is recorded and the automation does not fire.

`POST /v1/users/{userId}/automations/{automationId}/test-condition`

## Authentication

Both headers are required.

- Header: `X-Api-Key: YOUR_API_KEY`
- Header: `Authorization: Bearer YOUR_USER_TOKEN`

## Path parameters



```json
[
  {
    "schema": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "in": "path",
    "name": "userId",
    "required": true,
    "description": "The user in the path; must equal the token's own account."
  },
  {
    "schema": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    },
    "in": "path",
    "name": "automationId",
    "required": true,
    "description": "The automation's id."
  }
]
```


## Request body



```json
{
  "required": true,
  "content": {
    "application/json": {
      "schema": {
        "type": "object",
        "properties": {
          "event": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
                "description": "A caller-chosen id for this event, used to deduplicate replays."
              },
              "type": {
                "type": "string",
                "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,79}$",
                "description": "This event's own `type`, as the sender reports it."
              },
              "occurredAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                "description": "When this event happened, as the sender reports it."
              },
              "data": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "$ref": "#/components/schemas/AutomationJsonValueInput"
                },
                "description": "Arbitrary JSON data for this event: a manual invocation's or signal's payload, a reader's configuration, or a source plan's configuration. Bounded to 16 KiB, 8 levels of nesting and 256 entries."
              }
            },
            "required": [
              "id",
              "type",
              "occurredAt",
              "data"
            ],
            "additionalProperties": false,
            "description": "One event, shaped as an automation's inbound webhook receives it: an id, a type, when it happened, and its data. `automations.testCondition` accepts the same shape to evaluate a rule's condition against exactly the event given, without the type check a live delivery applies."
          }
        },
        "additionalProperties": false
      }
    }
  }
}
```


## Request example

Illustrative request. Replace the host, credentials and resource IDs with your own. If a request file is shown, create it from the schema above. Review the requested action before sending it.

```sh
curl --request POST 'https://api.example.test/v1/users/YOUR_USER_ID/automations/YOUR_AUTOMATION_ID/test-condition' \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --header 'Authorization: Bearer YOUR_USER_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{}'
```

## Responses

### 200

The condition's evaluation against the given event.



```json
{
  "description": "The condition's evaluation against the given event.",
  "content": {
    "application/json": {
      "schema": {
        "type": "object",
        "properties": {
          "definitionVersion": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991,
            "description": "The automation definition version this test evaluated against."
          },
          "evaluation": {
            "type": "object",
            "properties": {
              "verdict": {
                "type": "string",
                "enum": [
                  "true",
                  "false",
                  "unknown"
                ],
                "description": "Whether the rule's condition holds: `true` it fires, `false` it does not, `unknown` an input could not be read, so the rule neither fires nor is treated as false."
              },
              "evaluatedAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                "description": "When this evaluation ran."
              },
              "reasons": {
                "maxItems": 256,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "nodePath": {
                      "maxItems": 8,
                      "type": "array",
                      "items": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 9007199254740991
                      },
                      "description": "The path to the condition node this reason explains, as indices into the rule tree."
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "missing_source",
                        "unavailable",
                        "gap",
                        "stale",
                        "future",
                        "missing_field",
                        "invalid_value",
                        "snapshot_skew"
                      ],
                      "description": "Why this node could not cleanly resolve: `missing_source` no binding was configured, `unavailable` the provider did not answer, `gap` a break in coverage was recorded, `stale` or `future` a timestamp was out of range, `missing_field` the observation lacked this field, `invalid_value` the value did not match its declared type, `snapshot_skew` the inputs disagreed on when they were true."
                    },
                    "binding": {
                      "type": "string",
                      "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$",
                      "description": "The binding name a rule or a plan gives one configured source."
                    }
                  },
                  "required": [
                    "nodePath",
                    "code"
                  ]
                },
                "description": "Why the verdict is what it is, one entry per condition node that did not cleanly resolve."
              },
              "inputs": {
                "maxItems": 5,
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "binding": {
                          "type": "string",
                          "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$",
                          "description": "The binding name a rule or a plan gives one configured source."
                        },
                        "sourceId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128,
                          "description": "The source's id within its provider."
                        },
                        "eventId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128,
                          "description": "The observation or event's id."
                        },
                        "receivedAt": {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                          "description": "When the engine received this observation."
                        },
                        "maxAgeSeconds": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991,
                          "description": "How old this observation was allowed to be at evaluation, in seconds."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "ready",
                            "unavailable",
                            "gap"
                          ],
                          "description": "Whether this input was ready to evaluate, the provider was unavailable, or a gap was recorded instead."
                        },
                        "reason": {
                          "anyOf": [
                            {
                              "type": "string",
                              "maxLength": 512
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Why the input is not ready, when it is not."
                        },
                        "kind": {
                          "type": "string",
                          "description": "A point-in-time read of current state.",
                          "enum": [
                            "snapshot"
                          ]
                        },
                        "sourceTime": {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                          "description": "When the provider says this snapshot was true."
                        }
                      },
                      "required": [
                        "binding",
                        "sourceId",
                        "eventId",
                        "receivedAt",
                        "maxAgeSeconds",
                        "status",
                        "reason",
                        "kind",
                        "sourceTime"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "binding": {
                          "type": "string",
                          "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$",
                          "description": "The binding name a rule or a plan gives one configured source."
                        },
                        "sourceId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128,
                          "description": "The source's id within its provider."
                        },
                        "eventId": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128,
                          "description": "The observation or event's id."
                        },
                        "receivedAt": {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                          "description": "When the engine received this observation."
                        },
                        "maxAgeSeconds": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991,
                          "description": "How old this observation was allowed to be at evaluation, in seconds."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "ready",
                            "unavailable",
                            "gap"
                          ],
                          "description": "Whether this input was ready to evaluate, the provider was unavailable, or a gap was recorded instead."
                        },
                        "reason": {
                          "anyOf": [
                            {
                              "type": "string",
                              "maxLength": 512
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Why the input is not ready, when it is not."
                        },
                        "kind": {
                          "type": "string",
                          "description": "An event the source pushed, or the engine collected as it happened.",
                          "enum": [
                            "received_event"
                          ]
                        },
                        "sourceTime": {
                          "type": "null",
                          "description": "Not applicable to a received event; see `occurredAt` and `providerPublishedAt` instead."
                        },
                        "providerPublishedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "maxLength": 64,
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When the provider says it published this event, when it reports one."
                        },
                        "occurredAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When the event actually happened, when the provider reports that separately from when it was published."
                        },
                        "finalizedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When the provider considers this event no longer subject to correction, when it reports one."
                        }
                      },
                      "required": [
                        "binding",
                        "sourceId",
                        "eventId",
                        "receivedAt",
                        "maxAgeSeconds",
                        "status",
                        "reason",
                        "kind",
                        "sourceTime",
                        "providerPublishedAt",
                        "occurredAt",
                        "finalizedAt"
                      ]
                    }
                  ]
                },
                "description": "Each input this evaluation read, without its raw data."
              }
            },
            "required": [
              "verdict",
              "evaluatedAt",
              "reasons",
              "inputs"
            ],
            "description": "The condition's evaluation result: its verdict, the data it read, and why, when it did not cleanly resolve."
          }
        },
        "required": [
          "definitionVersion",
          "evaluation"
        ]
      }
    }
  }
}
```


### 400

The request could not be read as this operation expects.

- `invalid_input` — the body or query failed validation; `issues` names each field
- `invalid_cursor` — the `cursor` is not one this list minted



```json
{
  "description": "The request could not be read as this operation expects.\n\n- `invalid_input` — the body or query failed validation; `issues` names each field\n- `invalid_cursor` — the `cursor` is not one this list minted",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 401

A credential is missing, invalid or expired.

- `partner_key_required` — no `X-Api-Key` header was sent
- `partner_key_invalid` — the `X-Api-Key` is unknown or revoked
- `credential_expired` — the user token has expired; obtain a fresh one



```json
{
  "description": "A credential is missing, invalid or expired.\n\n- `partner_key_required` — no `X-Api-Key` header was sent\n- `partner_key_invalid` — the `X-Api-Key` is unknown or revoked\n- `credential_expired` — the user token has expired; obtain a fresh one",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 403

The credentials are valid but may not do this.

- `subject_mismatch` — the `{userId}` in the path is not the token's user
- `account_disabled` — an operator disabled the account
- `origin_rejected` — a browser `Origin` other than the configured web origin



```json
{
  "description": "The credentials are valid but may not do this.\n\n- `subject_mismatch` — the `{userId}` in the path is not the token's user\n- `account_disabled` — an operator disabled the account\n- `origin_rejected` — a browser `Origin` other than the configured web origin",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 404

The resource is missing, belongs to someone else, or its id is malformed: all three answer alike.



```json
{
  "description": "The resource is missing, belongs to someone else, or its id is malformed: all three answer alike.",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 412

The identity is verified but has no account yet.

- `account_not_provisioned` — the identity is verified but has no account yet; call `users.ensure` first



```json
{
  "description": "The identity is verified but has no account yet.\n\n- `account_not_provisioned` — the identity is verified but has no account yet; call `users.ensure` first",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 413

The body exceeds the size this deployment accepts.



```json
{
  "description": "The body exceeds the size this deployment accepts.",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 429

A limiter refused the request; honour `Retry-After`.

- `rate_limited` — the per-key or per-user limit is spent; honour `Retry-After`



```json
{
  "description": "A limiter refused the request; honour `Retry-After`.\n\n- `rate_limited` — the per-key or per-user limit is spent; honour `Retry-After`",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 500

A fault on our side; quote `requestId` when reporting it.

- `internal` — a fault on our side; quote `requestId` when reporting it



```json
{
  "description": "A fault on our side; quote `requestId` when reporting it.\n\n- `internal` — a fault on our side; quote `requestId` when reporting it",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


### 503

The replica is draining or a dependency did not answer; `retryable` says whether to try again.

- `internal` — a fault on our side; quote `requestId` when reporting it



```json
{
  "description": "The replica is draining or a dependency did not answer; `retryable` says whether to try again.\n\n- `internal` — a fault on our side; quote `requestId` when reporting it",
  "content": {
    "application/problem+json": {
      "schema": {
        "$ref": "#/components/schemas/ProblemDetails"
      }
    }
  }
}
```


## Complete OpenAPI definition

The exact operation and all referenced components, including recursive schemas.



```json
{
  "operation": {
    "operationId": "automations.testCondition",
    "summary": "Test condition",
    "tags": [
      "automations"
    ],
    "description": "Evaluates the automation's condition once, against the given event when one is supplied or against its retained source data otherwise. Nothing is recorded and the automation does not fire.",
    "requestBody": {
      "required": true,
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "event": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
                    "description": "A caller-chosen id for this event, used to deduplicate replays."
                  },
                  "type": {
                    "type": "string",
                    "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,79}$",
                    "description": "This event's own `type`, as the sender reports it."
                  },
                  "occurredAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "When this event happened, as the sender reports it."
                  },
                  "data": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "$ref": "#/components/schemas/AutomationJsonValueInput"
                    },
                    "description": "Arbitrary JSON data for this event: a manual invocation's or signal's payload, a reader's configuration, or a source plan's configuration. Bounded to 16 KiB, 8 levels of nesting and 256 entries."
                  }
                },
                "required": [
                  "id",
                  "type",
                  "occurredAt",
                  "data"
                ],
                "additionalProperties": false,
                "description": "One event, shaped as an automation's inbound webhook receives it: an id, a type, when it happened, and its data. `automations.testCondition` accepts the same shape to evaluate a rule's condition against exactly the event given, without the type check a live delivery applies."
              }
            },
            "additionalProperties": false
          }
        }
      }
    },
    "parameters": [
      {
        "schema": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
        },
        "in": "path",
        "name": "userId",
        "required": true,
        "description": "The user in the path; must equal the token's own account."
      },
      {
        "schema": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
        },
        "in": "path",
        "name": "automationId",
        "required": true,
        "description": "The automation's id."
      }
    ],
    "security": [
      {
        "apiKey": [],
        "userToken": []
      }
    ],
    "responses": {
      "200": {
        "description": "The condition's evaluation against the given event.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "definitionVersion": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991,
                  "description": "The automation definition version this test evaluated against."
                },
                "evaluation": {
                  "type": "object",
                  "properties": {
                    "verdict": {
                      "type": "string",
                      "enum": [
                        "true",
                        "false",
                        "unknown"
                      ],
                      "description": "Whether the rule's condition holds: `true` it fires, `false` it does not, `unknown` an input could not be read, so the rule neither fires nor is treated as false."
                    },
                    "evaluatedAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                      "description": "When this evaluation ran."
                    },
                    "reasons": {
                      "maxItems": 256,
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "nodePath": {
                            "maxItems": 8,
                            "type": "array",
                            "items": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 9007199254740991
                            },
                            "description": "The path to the condition node this reason explains, as indices into the rule tree."
                          },
                          "code": {
                            "type": "string",
                            "enum": [
                              "missing_source",
                              "unavailable",
                              "gap",
                              "stale",
                              "future",
                              "missing_field",
                              "invalid_value",
                              "snapshot_skew"
                            ],
                            "description": "Why this node could not cleanly resolve: `missing_source` no binding was configured, `unavailable` the provider did not answer, `gap` a break in coverage was recorded, `stale` or `future` a timestamp was out of range, `missing_field` the observation lacked this field, `invalid_value` the value did not match its declared type, `snapshot_skew` the inputs disagreed on when they were true."
                          },
                          "binding": {
                            "type": "string",
                            "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$",
                            "description": "The binding name a rule or a plan gives one configured source."
                          }
                        },
                        "required": [
                          "nodePath",
                          "code"
                        ]
                      },
                      "description": "Why the verdict is what it is, one entry per condition node that did not cleanly resolve."
                    },
                    "inputs": {
                      "maxItems": 5,
                      "type": "array",
                      "items": {
                        "oneOf": [
                          {
                            "type": "object",
                            "properties": {
                              "binding": {
                                "type": "string",
                                "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$",
                                "description": "The binding name a rule or a plan gives one configured source."
                              },
                              "sourceId": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 128,
                                "description": "The source's id within its provider."
                              },
                              "eventId": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 128,
                                "description": "The observation or event's id."
                              },
                              "receivedAt": {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                                "description": "When the engine received this observation."
                              },
                              "maxAgeSeconds": {
                                "type": "integer",
                                "exclusiveMinimum": 0,
                                "maximum": 9007199254740991,
                                "description": "How old this observation was allowed to be at evaluation, in seconds."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "ready",
                                  "unavailable",
                                  "gap"
                                ],
                                "description": "Whether this input was ready to evaluate, the provider was unavailable, or a gap was recorded instead."
                              },
                              "reason": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "maxLength": 512
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "Why the input is not ready, when it is not."
                              },
                              "kind": {
                                "type": "string",
                                "description": "A point-in-time read of current state.",
                                "enum": [
                                  "snapshot"
                                ]
                              },
                              "sourceTime": {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                                "description": "When the provider says this snapshot was true."
                              }
                            },
                            "required": [
                              "binding",
                              "sourceId",
                              "eventId",
                              "receivedAt",
                              "maxAgeSeconds",
                              "status",
                              "reason",
                              "kind",
                              "sourceTime"
                            ]
                          },
                          {
                            "type": "object",
                            "properties": {
                              "binding": {
                                "type": "string",
                                "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$",
                                "description": "The binding name a rule or a plan gives one configured source."
                              },
                              "sourceId": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 128,
                                "description": "The source's id within its provider."
                              },
                              "eventId": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 128,
                                "description": "The observation or event's id."
                              },
                              "receivedAt": {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                                "description": "When the engine received this observation."
                              },
                              "maxAgeSeconds": {
                                "type": "integer",
                                "exclusiveMinimum": 0,
                                "maximum": 9007199254740991,
                                "description": "How old this observation was allowed to be at evaluation, in seconds."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "ready",
                                  "unavailable",
                                  "gap"
                                ],
                                "description": "Whether this input was ready to evaluate, the provider was unavailable, or a gap was recorded instead."
                              },
                              "reason": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "maxLength": 512
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "Why the input is not ready, when it is not."
                              },
                              "kind": {
                                "type": "string",
                                "description": "An event the source pushed, or the engine collected as it happened.",
                                "enum": [
                                  "received_event"
                                ]
                              },
                              "sourceTime": {
                                "type": "null",
                                "description": "Not applicable to a received event; see `occurredAt` and `providerPublishedAt` instead."
                              },
                              "providerPublishedAt": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "maxLength": 64,
                                    "format": "date-time",
                                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "When the provider says it published this event, when it reports one."
                              },
                              "occurredAt": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "format": "date-time",
                                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "When the event actually happened, when the provider reports that separately from when it was published."
                              },
                              "finalizedAt": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "format": "date-time",
                                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "When the provider considers this event no longer subject to correction, when it reports one."
                              }
                            },
                            "required": [
                              "binding",
                              "sourceId",
                              "eventId",
                              "receivedAt",
                              "maxAgeSeconds",
                              "status",
                              "reason",
                              "kind",
                              "sourceTime",
                              "providerPublishedAt",
                              "occurredAt",
                              "finalizedAt"
                            ]
                          }
                        ]
                      },
                      "description": "Each input this evaluation read, without its raw data."
                    }
                  },
                  "required": [
                    "verdict",
                    "evaluatedAt",
                    "reasons",
                    "inputs"
                  ],
                  "description": "The condition's evaluation result: its verdict, the data it read, and why, when it did not cleanly resolve."
                }
              },
              "required": [
                "definitionVersion",
                "evaluation"
              ]
            }
          }
        }
      },
      "400": {
        "$ref": "#/components/responses/InvalidInput"
      },
      "401": {
        "$ref": "#/components/responses/Unauthorized"
      },
      "403": {
        "$ref": "#/components/responses/Forbidden"
      },
      "404": {
        "$ref": "#/components/responses/NotFound"
      },
      "412": {
        "$ref": "#/components/responses/AccountNotProvisioned"
      },
      "413": {
        "$ref": "#/components/responses/PayloadTooLarge"
      },
      "429": {
        "$ref": "#/components/responses/TooManyRequests"
      },
      "500": {
        "$ref": "#/components/responses/Internal"
      },
      "503": {
        "$ref": "#/components/responses/Unavailable"
      }
    }
  },
  "components": {
    "schemas": {
      "AutomationJsonValueInput": {
        "description": "Any JSON value: a string, number, boolean, null, array or object, nested to any depth.",
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AutomationJsonValueInput"
            }
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/AutomationJsonValueInput"
            }
          }
        ]
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "The kind of problem as a URN, `urn:fin:error:<kind>`; stable, compare against it"
          },
          "title": {
            "type": "string",
            "description": "The kind's human title, for logs; never parse it"
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599,
            "description": "The HTTP status, repeated in the body"
          },
          "reason": {
            "description": "The machine-readable why. One of:\n\n- `run_active` (409) — a run already holds this conversation\n- `budget_exhausted` (409) — the user's spend headroom is gone, or an operator froze it\n- `approval_not_pending` (409) — the approval was already decided or has expired, or its id does not exist or belongs to a different conversation\n- `execution_capacity` (409) — no execution capacity is free right now; `retryable` says whether to try again\n- `execution_unavailable` (409) — the execution engine could not take the work\n- `stop_pending` (409) — a stop is already in progress and its cleanup is not yet confirmed\n- `automation_changed` (409) — the `revision` sent is stale; reload the automation\n- `automation_held` (409) — an operator holds the automation; it fires again when released\n- `automation_invalid` (409) — the automation's definition cannot run as written\n- `automation_completed` (409) — the automation has finished for good and cannot fire again\n- `automation_limit` (409) — the user already has as many automations as the deployment allows\n- `profile_unknown_tool` (409) — the run profile names a tool this deployment does not have\n- `deployment_paused` (409) — an operator paused a deployment control; nothing was admitted or fired\n- `run_not_active` (409) — the run named in the path is not the conversation's live run\n- `withdrawal_changed` (409) — the withdrawal cannot be prepared or confirmed as asked: the balance no longer covers it, its terms changed or expired, or it is already in progress\n- `credential_expired` (401) — the user token has expired; obtain a fresh one\n- `account_disabled` (403) — an operator disabled the account\n- `account_not_provisioned` (412) — the identity is verified but has no account yet; call `users.ensure` first\n- `provider_unavailable` (503) — an external provider the call depends on did not answer\n- `engine_unavailable` (503) — the execution engine did not answer\n- `invalid_input` (400) — the body or query failed validation; `issues` names each field\n- `internal` (500) — a fault on our side; quote `requestId` when reporting it\n- `partner_key_required` (401) — no `X-Api-Key` header was sent\n- `partner_key_invalid` (401) — the `X-Api-Key` is unknown or revoked\n- `subject_mismatch` (403) — the `{userId}` in the path is not the token's user\n- `origin_rejected` (403) — a browser `Origin` other than the configured web origin\n- `permission_required` (403) — the operator credential lacks the scope this call needs\n- `rate_limited` (429) — the per-key or per-user limit is spent; honour `Retry-After`\n- `stream_capacity` (429) — no stream socket is free on this replica or for this user; honour `Retry-After`\n- `invalid_cursor` (400) — the `cursor` is not one this list minted",
            "type": "string",
            "enum": [
              "run_active",
              "budget_exhausted",
              "approval_not_pending",
              "execution_capacity",
              "execution_unavailable",
              "stop_pending",
              "automation_changed",
              "automation_held",
              "automation_invalid",
              "automation_completed",
              "automation_limit",
              "profile_unknown_tool",
              "deployment_paused",
              "run_not_active",
              "withdrawal_changed",
              "credential_expired",
              "account_disabled",
              "account_not_provisioned",
              "provider_unavailable",
              "engine_unavailable",
              "invalid_input",
              "internal",
              "partner_key_required",
              "partner_key_invalid",
              "subject_mismatch",
              "origin_rejected",
              "permission_required",
              "rate_limited",
              "stream_capacity",
              "invalid_cursor"
            ]
          },
          "requestId": {
            "type": "string",
            "description": "The id Fin used for this request; quote it when reporting a problem"
          },
          "retryable": {
            "type": "boolean",
            "description": "Whether repeating the same request later can succeed without changing it"
          },
          "detail": {
            "description": "Only on `invalid_input`: which part of the request failed validation",
            "type": "string"
          },
          "issues": {
            "description": "Only on `invalid_input`: one entry per failing field",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string",
                  "description": "The JSON pointer of the failing field; empty for the root object"
                },
                "message": {
                  "type": "string",
                  "description": "Why the field failed"
                }
              },
              "required": [
                "path",
                "message"
              ]
            }
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "requestId",
          "retryable"
        ],
        "description": "RFC 9457 problem details: what every error response carries. Never a provider's message, a query or a stack."
      }
    },
    "responses": {
      "InvalidInput": {
        "description": "The request could not be read as this operation expects.\n\n- `invalid_input` — the body or query failed validation; `issues` names each field\n- `invalid_cursor` — the `cursor` is not one this list minted",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "A credential is missing, invalid or expired.\n\n- `partner_key_required` — no `X-Api-Key` header was sent\n- `partner_key_invalid` — the `X-Api-Key` is unknown or revoked\n- `credential_expired` — the user token has expired; obtain a fresh one",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The credentials are valid but may not do this.\n\n- `subject_mismatch` — the `{userId}` in the path is not the token's user\n- `account_disabled` — an operator disabled the account\n- `origin_rejected` — a browser `Origin` other than the configured web origin",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "NotFound": {
        "description": "The resource is missing, belongs to someone else, or its id is malformed: all three answer alike.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "AccountNotProvisioned": {
        "description": "The identity is verified but has no account yet.\n\n- `account_not_provisioned` — the identity is verified but has no account yet; call `users.ensure` first",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "The body exceeds the size this deployment accepts.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "A limiter refused the request; honour `Retry-After`.\n\n- `rate_limited` — the per-key or per-user limit is spent; honour `Retry-After`",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Internal": {
        "description": "A fault on our side; quote `requestId` when reporting it.\n\n- `internal` — a fault on our side; quote `requestId` when reporting it",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      },
      "Unavailable": {
        "description": "The replica is draining or a dependency did not answer; `retryable` says whether to try again.\n\n- `internal` — a fault on our side; quote `requestId` when reporting it",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      },
      "userToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  }
}
```

